SM2加解密

一、引用BC Maven包

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.59</version>
        </dependency>


二、SM2工具类

import org.apache.commons.codec.binary.Base64;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import sun.misc.BASE64Decoder;

import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;


@Slf4j
public class SM2Utils {

    private final static String PUBLIC_KEY_STR = "生成的公钥";
    private final static String PRIVATE_KEY_STR = "生成的私钥";


    /**
     * 默认加密
     * @param data
     * @return
     */
    public static String encrypt(String data){
       return encrypt(PUBLIC_KEY_STR,data);
    }

    /**
     * SM2加密算法
     * @param publicKeyStr     公钥
     * @param data          明文数据
     * @return
     */
    public static String encrypt(String publicKeyStr, String data){
        Security.addProvider(new BouncyCastleProvider());
        PublicKey publicKey = null;
        try {
            log.info("开始转换字符串公钥,公钥值:{},数据值:{}",publicKeyStr,data);
            byte[] keyBytes;
            keyBytes = (new BASE64Decoder()).decodeBuffer(publicKeyStr);
            KeyFactory keyFactory = KeyFactory.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            publicKey = keyFactory.generatePublic(keySpec);
            log.info("转换后的公钥:{}",publicKey);
        } catch (Exception e) {
            log.error("SM2字符串公钥转换异常:{}",e.getMessage());
            throw new RuntimeException("SM2字符串公钥转换异常");
        }
        log.info("SM2开始加密数据");
        ECPublicKeyParameters ecPublicKeyParameters = null;
        if (publicKey instanceof BCECPublicKey) {
            BCECPublicKey bcecPublicKey = (BCECPublicKey) publicKey;
            ECParameterSpec ecParameterSpec = bcecPublicKey.getParameters();
            ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
                    ecParameterSpec.getG(), ecParameterSpec.getN());
            ecPublicKeyParameters = new ECPublicKeyParameters(bcecPublicKey.getQ(), ecDomainParameters);
        }
        SM2Engine sm2Engine = new SM2Engine();
        sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom()));
        byte[] arrayOfBytes = null;
        try {
            byte[] in = data.getBytes("utf-8");
            arrayOfBytes = sm2Engine.processBlock(in,0, in.length);
        } catch (Exception e) {
            log.error("SM2加密时出现异常:",e.getMessage());
            throw new RuntimeException("SM2加密时出现异常:");
        }
        return  Base64.encodeBase64String(arrayOfBytes);
    }

    /**
     * 默认解密
     * @param cipherData
     * @return
     */
    public static String decrypt(String cipherData){
        return decrypt(PRIVATE_KEY_STR,cipherData);
    }

    /**
     * SM2解密算法
     * @param privateKeyStr        私钥
     * @param cipherData        密文数据
     * @return
     */
    public static String decrypt(String privateKeyStr, String cipherData){

        PrivateKey privateKey = null;
        byte[] keyBytes;
        try {
            Security.addProvider(new BouncyCastleProvider());

            keyBytes = (new BASE64Decoder()).decodeBuffer(privateKeyStr);
            KeyFactory keyFactory = KeyFactory.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
            privateKey=keyFactory.generatePrivate(keySpec);
        }catch (Exception e){
            log.error("SM2字符串私钥转换异常:{}",e.getMessage());
            throw new RuntimeException("SM2字符串私钥转换异常");
        }

        BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) privateKey;
        ECParameterSpec ecParameterSpec = bcecPrivateKey.getParameters();
        ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
                ecParameterSpec.getG(), ecParameterSpec.getN());
        ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(bcecPrivateKey.getD(),
                ecDomainParameters);
        SM2Engine sm2Engine = new SM2Engine();
        sm2Engine.init(false, ecPrivateKeyParameters);
        String result = null;

        byte[] arrayOfBytes = null;
        try {
            byte[] in = Base64.decodeBase64(cipherData);
            arrayOfBytes = sm2Engine.processBlock(in,0, in.length);
            result=new String(arrayOfBytes, "utf-8");
        } catch (Exception e) {
           throw new RuntimeException("SM2解密时出现异常");
        }
        return result;
    }


    /**
     * SM2算法生成密钥对
     * @return 密钥对信息
     */
    public static KeyPair generateSm2KeyPair() {
        try {
            final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
            // 获取一个椭圆曲线类型的密钥对生成器
            final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
            SecureRandom random = new SecureRandom();
            // 使用SM2的算法区域初始化密钥生成器
            kpg.initialize(sm2Spec, random);
            // 获取密钥对
            KeyPair keyPair = kpg.generateKeyPair();
            return keyPair;
        } catch (Exception e) {
            log.error("generate sm2 key pair failed:{}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * main 方法测试
     **/
    public static void main(String[] args) {
//        KeyPair keyPair = SM2Utils.generateSm2KeyPair();
//        String privateKey = Base64.encodeBase64String(keyPair.getPrivate().getEncoded());
//        String publicKey  = Base64.encodeBase64String(keyPair.getPublic().getEncoded());
//
//        log.info("公钥:"+publicKey);
//        log.info("私钥:"+privateKey);

        String data="123456";
      
        String encrypt = SM2Utils.encrypt(PUBLIC_KEY_STR,data);
        String decrypt = SM2Utils.decrypt(PRIVATE_KEY_STR, encrypt);

        log.info("加密后数据:"+encrypt);
        log.info("解密后数据:"+decrypt);
    }

}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我可以为您提供一些关于 JavaScript 和 JavaSM2 加解密的基本信息。 JavaScript 中的 SM2 加解密可以使用 jsrsasign 库进行实现。以下是一个简单的示例代码: ```javascript // 密钥对生成 var ec = new KJUR.crypto.ECDSA({'curve': 'sm2'}); var keypair = ec.generateKeyPairHex(); // 加密 var pubKey = keypair.ecpubhex; var plainText = 'hello world'; var cipher = KJUR.crypto.Cipher.encrypt(pubKey, plainText, 'SM2'); // 解密 var privKey = keypair.ecprvhex; var decrypted = KJUR.crypto.Cipher.decrypt(privKey, cipher, 'SM2'); console.log(decrypted); ``` Java 中的 SM2 加解密可以使用 Bouncy Castle 库进行实现。以下是一个简单的示例代码: ```java // 密钥对生成 ECNamedCurveParameterSpec sm2Spec = ECNamedCurveTable.getParameterSpec("sm2p256v1"); KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider()); kpg.initialize(sm2Spec, new SecureRandom()); KeyPair keyPair = kpg.generateKeyPair(); // 加密 Cipher cipher = Cipher.getInstance("SM2", new BouncyCastleProvider()); cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic()); byte[] plainText = "hello world".getBytes(); byte[] cipherText = cipher.doFinal(plainText); // 解密 cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); byte[] decrypted = cipher.doFinal(cipherText); System.out.println(new String(decrypted)); ``` 需要注意的是,JavaScript 和 Java 中的 SM2 加解密算法的实现细节可能有所不同,需要根据具体需求进行调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值