【实战】国密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 文件引入如下:

  1.     <dependencies>
  2.         <dependency>
  3.             <groupId>cn.hutool</groupId>
  4.             <artifactId>hutool-all</artifactId>
  5.             <version>5.8.5</version>
  6.         </dependency>
  7.         <dependency>
  8.             <groupId>org.bouncycastle</groupId>
  9.             <artifactId>bcpkix-jdk15on</artifactId>
  10.             <version>1.60</version>
  11.         </dependency>
  12.     </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 命令如下:

  1. Install-Package Sw.ChinaEncryptSM -Version 1.0.0
复制代码


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

测试 .NET 和 Java 加密结果

.NET 代码:

  1. using Sw.ChinaEncryptSM;
  2.  
  3. var key = "xG1BWyO9jGmehXTFkhiNSQ==";
  4. var iv = "v3mVmxORBMedfZWsIRRloQ==";
  5. SM4Utils sM4Utils = new SM4Utils()
  6. {
  7.     secretKey = key,
  8.     iv = iv
  9. };
  10. var result1 = sM4Utils.Encrypt_CBC_Base64("小渣渣 itsvse.com");
  11. Console.WriteLine("加密结果如下:");
  12. Console.WriteLine(result1);
  13.  
复制代码

Java 代码:

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

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



.NET 加解密和 Java 解密

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

.NET 代码:

  1. using Sw.ChinaEncryptSM;
  2.  
  3. var key = "xG1BWyO9jGmehXTFkhiNSQ==";
  4. var iv = "v3mVmxORBMedfZWsIRRloQ==";
  5. SM4Utils sM4Utils = new SM4Utils()
  6. {
  7.     secretKey = key,
  8.     iv = iv
  9. };
  10. var result1 = sM4Utils.Encrypt_CBC_Base64("Test 小渣渣 itsvse.com");
  11. Console.WriteLine("加密结果如下:");
  12. Console.WriteLine(result1);
  13. Console.WriteLine("解密结果如下:");
  14. var result2 = sM4Utils.Decrypt_CBC_Base64(result1);
  15. Console.WriteLine(result2);
  16.  
复制代码

Java 代码:

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

如下图:

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




(完)

posted @ 2023-05-05 20:37  _小渣渣  阅读(1270)  评论(0编辑  收藏  举报