国密SM2算法

106 阅读1分钟

描述

SM2算法类似RSA(非对称加密算法)算法

实现步骤

  • 引入maven依赖
<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcprov-jdk18on</artifactId>
  <version>1.77</version>
</dependency>
<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcpkix-jdk15on</artifactId>
  <version>1.70</version>
</dependency>
  • SM2的java实现代码
package org.example.test;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;

import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class SM2Test {

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static void main(String[] args) throws InvalidAlgorithmParameterException,
            NoSuchAlgorithmException,
            NoSuchProviderException,
            InvalidKeyException,
            InvalidCipherTextException,
            InvalidKeySpecException {

//        // 初始化密钥生成器
//        KeyPairGenerator generator = KeyPairGenerator.getInstance("EC", "BC");
//        ECGenParameterSpec ecSpec = new ECGenParameterSpec("sm2p256v1");
//        generator.initialize(ecSpec, new SecureRandom());
//        KeyPair keyPair = generator.generateKeyPair();
//
//        // 提取公钥和私钥
//        PublicKey publicKey = keyPair.getPublic();
//        PrivateKey privateKey = keyPair.getPrivate();
//
//        System.out.println(Base64.toBase64String(publicKey.getEncoded()));
//
//        System.out.println(Base64.toBase64String(privateKey.getEncoded()));

        String publicStr = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAExDwKGxieYLPOHa4M8lwKKjY5YW+oK07w/YhE6fZmJtFeyRgz/DywukVWirCfmFT0axnU3741a6vt2uqLIAe9ZA==";

        String privateStr = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQggFR8H5ZGWwuCmndzuv2OtHtMuK0UnZOiMqFVgorP1yGgCgYIKoEcz1UBgi2hRANCAATEPAobGJ5gs84drgzyXAoqNjlhb6grTvD9iETp9mYm0V7JGDP8PLC6RVaKsJ+YVPRrGdTfvjVrq+3a6osgB71k";


        byte[] decodePublicStr = Base64.decode(publicStr);

        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decodePublicStr);

        KeyFactory instance = KeyFactory.getInstance("EC", "BC");

        PublicKey publicKey = instance.generatePublic(x509EncodedKeySpec);
        // 转换公钥为BC格式参数
        ECPublicKeyParameters pubKeyParams = (ECPublicKeyParameters)
                ECUtil.generatePublicKeyParameter(publicKey);

        // 初始化加密引擎(C1C3C2模式)
        SM2Engine engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
        engine.init(true, new ParametersWithRandom(pubKeyParams, new SecureRandom()));

        // 加密数据
        byte[] plaintext = "Hello SM2".getBytes(StandardCharsets.UTF_8);
        byte[] ciphertext = engine.processBlock(plaintext, 0, plaintext.length);


        byte[] decodePrivateStr = Base64.decode(privateStr);
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decodePrivateStr);
        KeyFactory instance1 = KeyFactory.getInstance("EC", "BC");
        PrivateKey privateKey = instance1.generatePrivate(pkcs8EncodedKeySpec);

        // 转换私钥为BC格式参数
        ECPrivateKeyParameters priKeyParams = (ECPrivateKeyParameters)
                ECUtil.generatePrivateKeyParameter(privateKey);

        // 初始化解密引擎(需与加密模式一致)
        SM2Engine engine2 = new SM2Engine(SM2Engine.Mode.C1C3C2);
         // 初始化解密引擎(需与加密模式一致)
        engine2.init(false, priKeyParams);

        // 解密数据
        byte[] decrypted = engine2.processBlock(ciphertext, 0, ciphertext.length);
        String result = new String(decrypted, StandardCharsets.UTF_8);

        System.out.println(result);

    }
}