SM2加解密工具

发布时间 2023-04-24 15:51:32作者: 老YAN
点击查看代码
//生成随机秘钥对
public static SM2KeyPairVO generateKeyPair() {
    try {
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
        ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
        keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
        AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();
        //私钥,16进制格式,自己保存,格式如a2081b5b81fbea0b6b973a3ab6dbbbc65b1164488bf22d8ae2ff0b8260f64853
        BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
        String privateKeyHex = privatekey.toString(16);
        //公钥,16进制格式,发给前端,格式如04813d4d97ad31bd9d18d785f337f683233099d5abed09cb397152d50ac28cc0ba43711960e811d90453db5f5a9518d660858a8d0c57e359a8bf83427760ebcbba
        ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
        String publicKeyHex = Hex.toHexString(ecPoint.getEncoded(false));
        SM2KeyPairVO sm2KeyPairVO = new SM2KeyPairVO();
        sm2KeyPairVO.setPrivateKey(privateKeyHex);
        sm2KeyPairVO.setPublicKey(publicKeyHex);
        return sm2KeyPairVO;
    } catch (Exception e) {
        log.error("SM2密钥对生成失败失败,原因是:" + e.getMessage());
    }
    return null;
}
点击查看代码
/**
 * SM2加密算法
 * @param publicKey 公钥
 * @param data     数据
 * @return
 */
public static String encrypt(String publicKey,String data){
    //获取一条曲线参数
    X9ECParameters sm2ECParam = GMNamedCurves.getByName("sm2p256v1");
    ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParam.getCurve(), sm2ECParam.getG(), sm2ECParam.getN());
    //提取公钥点
    ECPoint pukPoint = sm2ECParam.getCurve().decodePoint(Hex.decode(publicKey));
    //公钥值
    ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);
    //做加签
    SM2Engine sm2Engine = new SM2Engine();
    sm2Engine.init(true,new ParametersWithRandom(publicKeyParameters,new SecureRandom()));
    byte[] arrayOfBytes = null;
    try{
        byte[] in = data.getBytes(Constants.CHARSET_UTF8);
        arrayOfBytes = sm2Engine.processBlock(in,0,in.length);
    } catch (Exception e) {
        log.error("SM2加密失败");
    }
    return Hex.toHexString(arrayOfBytes);
}
点击查看代码
/**
 * SM2解密算法
 * @param privateKey 私钥
 * @param CipherData 密文数据
 * @return
 */
public static String decryptSM2(String privateKey,String CipherData){
    byte[] cipherDateByte = Hex.decode(CipherData);
    //获取一条曲线参数
    X9ECParameters sm2ECParam = GMNamedCurves.getByName("sm2p256v1");
    //构造domain参数
    ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParam.getCurve(), sm2ECParam.getG(), sm2ECParam.getN());
    BigInteger privateKeyD = new BigInteger(privateKey, 16);
    ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
    //做解签
    SM2Engine sm2Engine = new SM2Engine();
    sm2Engine.init(false,privateKeyParameters);
    String result = null;
    try{
        byte[] arrayOfBytes = Base64.decode(sm2Engine.processBlock(cipherDateByte, 0, cipherDateByte.length));
        return new String(arrayOfBytes,Constants.CHARSET_UTF8);
    } catch (Exception e) {
        log.error("SM2解密失败");
    }
    return result;
}
点击查看代码
public static void main(String[] args) {
    SM2KeyPairVO sm2KeyPairVO = generateKeyPair();
    String pKey = sm2KeyPairVO.getPublicKey();
    String priKey = sm2KeyPairVO.getPrivateKey();
    System.out.println("公钥为: " + pKey);
    System.out.println("私钥为: " + priKey);
    String publicKey = pKey;
    String privateKey = priKey;
    String content = "hello";
    String encrypt = encrypt(publicKey, Base64.toBase64String(content.getBytes(StandardCharsets.UTF_8)));
    System.out.println("密文:" + encrypt);
    String test = decryptSM2(privateKey, encrypt);
    System.out.println("解密:" + test);
}