基于 BC 包实现国密

admin 2024年3月7日08:03:30评论5 views字数 5078阅读16分55秒阅读模式

前言

对于很多企业来说,都在进行国密改造,要求使用国密代替传统的国际算法,国密算法分为 SM1、SM2、SM3、SM4,比较常见是的 2-4:

  1. 对称加密算法

    • SM4:SM4算法是一种128位分组加密算法,密钥长度也为128位,适用于大量数据的快速加密。

  2. 非对称加密算法

    • SM2:SM2算法基于椭圆曲线密码学,用于实现公钥加密和数字签名。它包括密钥生成、加密、解密和数字签名等功能。

  3. 哈希算法

    • SM3:SM3是一种密码哈希函数,用于生成消息摘要,可用于数据完整性校验、消息认证码(MAC)生成等用途。

  4. 数字签名算法

    • SM2算法也用于数字签名,通过私钥对消息摘要进行签名,公钥用于验证签名的真实性。

通过 JAVA 代码分别实现

常见 maven 仓库,在 pom 中加载 BC 包:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15to18</artifactId>
    <version>1.72</version>
</dependency>

对 SM2-4 实现的代码如下,供大家参考

1package com.example.bc;

3import java.security.KeyPair;
4import java.security.KeyPairGenerator;
5import java.security.SecureRandom;
6import java.security.Security;

8import javax.crypto.Cipher;
9import javax.crypto.spec.SecretKeySpec;
10import javax.crypto.spec.IvParameterSpec;

12import org.bouncycastle.asn1.bc.SignatureCheck;
13import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
14import org.bouncycastle.asn1.ocsp.Signature;
15import org.bouncycastle.crypto.CipherParameters;
16import org.bouncycastle.crypto.digests.SM3Digest;
17import org.bouncycastle.crypto.macs.HMac;
18import org.bouncycastle.crypto.params.KeyParameter;
19import org.bouncycastle.crypto.params.ParametersWithRandom;
20import org.bouncycastle.crypto.signers.SM2Signer;
21import org.bouncycastle.jce.provider.BouncyCastleProvider;
22import org.bouncycastle.util.encoders.Hex;

24/**
25.  * Hello world!
26.  *
27.  */

28public class App 
29. 
{
30.     public static void main( String[] args ) throws Exception
31.     
{
32.         //加载 bc provider
33.         Security.addProvider(new BouncyCastleProvider());
34.         String plainText = "HelloWord!";
35.         byte[] messagebytes = plainText.getBytes();
36.         SecureRandom secureRandom = new SecureRandom();

38.         // 生成密钥
39.         System.out.println("Demo1: sm2 加解密:n");
40.         KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC""BC");
41.         keyPairGenerator.initialize(256, secureRandom);
42.         KeyPair keyPair = keyPairGenerator.generateKeyPair();
43.         System.out.println("公钥:" + Hex.toHexString(keyPair.getPublic().getEncoded()));
44.         System.out.println("私钥:" + Hex.toHexString(keyPair.getPrivate().getEncoded()));
45.         //加密

47.         Cipher cipher = Cipher.getInstance("SM2","BC");
48.         cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
49.         byte[] encryptedbytes = cipher.doFinal(messagebytes);
50.         System.out.println("加密后:" + Hex.toHexString(encryptedbytes));
51.         //解密
52.         Cipher cipher1 = Cipher.getInstance("SM2","BC");
53.         cipher1.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
54.         byte[] decryptedbytes = cipher1.doFinal(encryptedbytes);
55.         System.out.println("解密后:" + new String(decryptedbytes));

57.         System.out.println("---------------------------------------------------------");
58.         System.out.println("Demo2: sm3 哈希:n");
59.         SM3Digest sm3 = new SM3Digest();
60.         sm3.update(messagebytes,0,messagebytes.length);
61.         byte[] result = new byte[sm3.getDigestSize()];
62.         sm3.doFinal(result, 0);
63.         System.out.println("哈希后:" + Hex.toHexString(result));

65.         System.out.println("---------------------------------------------------------");
66.         System.out.println("Demo3: sm4 加解密:n");
67.         //生成随机数作为密钥和 IV 值
68.         byte[] key = new byte[16];
69.         secureRandom.nextBytes(key);
70.         byte[] iv = new byte[16];
71.         secureRandom.nextBytes(iv);
72.         // IvAlgorithmParameters ivSpec = new IvAlgorithmParameters();
73.         IvParameterSpec ivSpec = new IvParameterSpec(iv);

75.         System.out.println("密钥:" + Hex.toHexString(key));
76.         System.out.println("向量:" + Hex.toHexString(iv));

78.         Cipher cipher2 = Cipher.getInstance("SM4/CBC/PKCS5Padding","BC");
79.         cipher2.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "SM4"), ivSpec);
80.         byte[] encryptedbytes2 = cipher2.doFinal(messagebytes);
81.         System.out.println("加密后:" + Hex.toHexString(encryptedbytes2));
82.         cipher2.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "SM4"), ivSpec);
83.         byte[] decryptedbytes2 = cipher2.doFinal(encryptedbytes2);
84.         System.out.println("解密后:" + new String(decryptedbytes2));

86.         //Hmac算法
87.         System.out.println("---------------------------------------------------------");
88.         System.out.println("Demo4: sm4 hmac:n");
89.         byte[] key2 = new byte[16];
90.         secureRandom.nextBytes(key2);
91.         System.out.println("密钥:" + Hex.toHexString(key2));

93.         HMac hMac = new HMac(new SM3Digest());
94.         hMac.init(new KeyParameter(key));
95.         hMac.update(messagebytes,0,messagebytes.length);
96.         byte[] result2 = new byte[hMac.getMacSize()];
97.         hMac.doFinal(result2, 0);
98.         System.out.println("hmac后:" + Hex.toHexString(result2));

100.     }

102. }

其他可使用的包

腾讯Kona国密套件(如KonaCrypto),该套件已在GitHub上开源:https://github.com/Tencent/TencentKonaSMSuite,相对于 BC 来说可能更好用一些,BC 貌似对签名验签并不支持,在使用 BC 包的时候没能实现签名验签的代码。


原文始发于微信公众号(YY的黑板报):基于 BC 包实现国密

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月7日08:03:30
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   基于 BC 包实现国密https://cn-sec.com/archives/2552525.html

发表评论

匿名网友 填写信息