需求:由于朋友项目上需要和第三方对接,数据在传输过程中使用国密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
(完)