Bouncycastle1.60实现加解密、密钥存储、签名验签

1 版本概述

    原来项目中使用的是Bouncycastle1.46版本的,后由于项目需要,改成了1.60版本。本文基于1.60版本实现加密解密、本地存储、签名验签功能。本文代码已上线稳定运行,现整理干货如下。首先在项目中添加如下依赖:

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

<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcpkix-jdk15on</artifactId>
  <version>1.60</version>
</dependency>

2 代码实现

    编写加解密工具类,直接贴代码了(包含测试代码),略显粗糙,读者可优化该工具类GmUtil,详见生成密钥:generateKeyPair、加密:sm2Encrypt、解密sm2Decrypt等方法:3 密钥存储实现

   若需要存储密钥,则上述生成的KeyPair对象无法存在特定的文件或数据库中,我们需要将其转化成字符串型的数据,方式如下:

/*
 *
 *KeyPair密钥转String型密钥
 */
public static List<String> getStringKey(KeyPair keyPair){
    // 公钥转换
    PublicKey publicKey = keyPair.getPublic();
    BCECPublicKey localECPublicKEy = (BCECPublicKey)publicKey;
    ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(localECPublicKEy.getQ(),ecDomainParameters);
    byte[] publicKeyByte = ecPublicKeyParameters.getQ().getEncoded(false);
    String publicKeyStr = TransferUtil.byteToHex(publicKeyByte);
    PrivateKey privateKey = keyPair.getPrivate();
    BCECPrivateKey bcecPrivateKey = (BCECPrivateKey)privateKey;
    BigInteger privateKeyBI = bcecPrivateKey.getD();
    byte[] privateKeyByte = TransferUtil.biConvert32Bytes(privateKeyBI);
    String privateKeyStr = TransferUtil.byteToHex(privateKeyByte);

    System.out.println("公钥: "+publicKeyStr);
    System.out.println("私钥: "+privateKeyStr);
    List<String> keyPairList = new ArrayList<>(2);
    // 公私钥字符串存入list
    byte[] temp = TransferUtil.hexToByte(privateKeyStr);

    keyPairList.add(publicKeyStr);
    keyPairList.add(privateKeyStr);
    return keyPairList;
}

/*
 *
 *用String型公钥加密
 */
private static String encrypt(String data,String pubKey){
    //构造ECPoint
    ECPoint ecPoint = SM2Util.CURVE.decodePoint(TransferUtil.hexStringToBytes(pubKey));
    ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(ecPoint,GmUtil.ecDomainParameters);
    SM2Engine sm2Engine = new SM2Engine();
    sm2Engine.init(true,new ParametersWithRandom(ecPublicKeyParameters,new SecureRandom()));
    byte[] byteResult;
    try{
        byte[] byteData = data.getBytes();
        byte[] temp = sm2Engine.processBlock(byteData,0,byteData.length);
        byteResult = changeC1C2C3ToC1C3C2(temp);
    }catch (InvalidCipherTextException e){
        throw new RuntimeException(e);
    }
    return Hex.toHexString(byteResult);
}

/*
 *
 *用String私钥解密
 */
private static String decrypt(String encryptedData,String privateKey){
    byte[] priKeyByte = TransferUtil.hexToByte(privateKey);
    ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(new BigInteger(1,priKeyByte),ecDomainParameters);
    SM2Engine sm2Engine = new SM2Engine();
    sm2Engine.init(false,ecPrivateKeyParameters);
    byte[] result = null;
    try{
        byte[] encryptDataByte = TransferUtil.hexToByte(encryptedData);
        byte[] temp = changeC1C3C2ToC1C2C3(encryptDataByte);
        result = sm2Engine.processBlock(temp,0,temp.length);
    }catch (Exception e){
        e.printStackTrace();
    }
    return new String(result);
}

4 测试加解密:

//生成公私钥
KeyPair kp = generateKeyPair();
Lisy<String> keys = getStringKey(kp);
//加解密测试
String pub = "0471569510119CB9182D757942A36A61F052E155FCB795956445D33ACBA8972F0CAF47DDE468D48D7080640244C1BBC46199AFB88C974F6020B590B3DA5C1FBA00";
String pri = "8D704AE2D67CBF865224ADA883FE9F32D6CAFDEEC9A7E9D9999010856F71C2FB";
String temp = encrypt("hello world!",pub);
System.out.println("加密后的数据: "+temp);
System.out.println("解密出的数据: "+decrypt(temp,pri));
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值