【实战】国密4(SM4)使用 .NET 和 Java 相互加解密
需求:由于朋友项目上需要和第三方对接,数据在传输过程中使用国密4(SM4)算法进行了加密,需要双方对数据进行加密和解密操作,第三方使用的是 Java 开发的项目,朋友使用的是 .NET 开发的项目。

SM4.0(原名SMS4.0)是中华人民共和国政府采用的一种分组密码标准,由国家密码管理局于2012年3月21日发布。相关标准为“GM/T 0002-2012《SM4分组密码算法》(原SMS4分组密码算法)”。

信息安全技术 SM4分组密码算法:https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=7803DE42D3BC5E80B0C3E5D8E873D56A

Java 项目

新建了一个 maven 项目,引入了 hutool 工具,使用 hutool 中封装好的 SM4 算法,pom 文件引入如下:



    <dependencies>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.5</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk15on</artifactId>
            <version>1.60</version>
        </dependency>
    </dependencies>

复制代码
文档:https://hutool.cn/docs/#/crypto/%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86-SymmetricCrypto

.NET 项目

.NET 项目需要引入我封装好的 Sw.ChinaEncryptSM 包,支持 .NET Framework 和 .NET Core 项目,使用 nuget 命令如下:



Install-Package Sw.ChinaEncryptSM -Version 1.0.0

复制代码

地址:https://www.nuget.org/packages/Sw.ChinaEncryptSM/

测试 .NET 和 Java 加密结果

.NET 代码:



using Sw.ChinaEncryptSM;

var key = "xG1BWyO9jGmehXTFkhiNSQ==";
var iv = "v3mVmxORBMedfZWsIRRloQ==";
SM4Utils sM4Utils = new SM4Utils()
{
    secretKey = key,
    iv = iv
};
var result1 = sM4Utils.Encrypt_CBC_Base64("小渣渣 itsvse.com");
Console.WriteLine("加密结果如下:");
Console.WriteLine(result1);

复制代码
Java 代码:


  SymmetricCrypto sm4 = new SymmetricCrypto("SM4/CBC/PKCS5Padding",Base64.decode("xG1BWyO9jGmehXTFkhiNSQ=="));
                sm4.setIv(Base64.decode("v3mVmxORBMedfZWsIRRloQ=="));
                byte[] result= sm4.encrypt("小渣渣 itsvse.com");
                System.out.println("加密后: " + Base64.encode(result));

复制代码
可以看到在 key 和 iv 相同的情况下,加密后的结果是一样的,如下图:

.NET 加解密和 Java 解密

此处略去使用 Java 加密 .NET 加密的代码,大家举一反三即可。

.NET 代码:



using Sw.ChinaEncryptSM;

var key = "xG1BWyO9jGmehXTFkhiNSQ==";
var iv = "v3mVmxORBMedfZWsIRRloQ==";
SM4Utils sM4Utils = new SM4Utils()
{
    secretKey = key,
    iv = iv
};
var result1 = sM4Utils.Encrypt_CBC_Base64("Test 小渣渣 itsvse.com");
Console.WriteLine("加密结果如下:");
Console.WriteLine(result1);
Console.WriteLine("解密结果如下:");
var result2 = sM4Utils.Decrypt_CBC_Base64(result1);
Console.WriteLine(result2);

复制代码
Java 代码:


  SymmetricCrypto sm4 = new SymmetricCrypto("SM4/CBC/PKCS5Padding",Base64.decode("xG1BWyO9jGmehXTFkhiNSQ=="));
                sm4.setIv(Base64.decode("v3mVmxORBMedfZWsIRRloQ=="));
                byte[] result = sm4.decrypt(Base64.decode("rG50B+Ah6k0FqvvKItc2TDJnt9HcDIG9OyjBqkiiAlI="));
                System.out.println("明文: " + new String(result, StandardCharsets.UTF_8));

复制代码
如下图:

加密结果如下:
rG50B+Ah6k0FqvvKItc2TDJnt9HcDIG9OyjBqkiiAlI=
解密结果如下:
Test 小渣渣 itsvse.com

文档更新时间: 2023-05-28 16:10   作者:admin