赞
踩
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<version>1.69</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.10</version>
</dependency>
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.HexUtil; import cn.hutool.crypto.BCUtil; import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.SM2; import cn.hutool.core.codec.Base64; import org.bouncycastle.asn1.*; import org.bouncycastle.asn1.gm.GMNamedCurves; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.math.ec.ECPoint; import java.io.IOException; import java.math.BigInteger; import java.util.Arrays; public class SM2Util { private static final int C1_LEN = 65; private static final int C3_LEN = 32; /** * 将c1c3c2转成标准的ASN1格式 */ public static byte[] changeC1C3C2ToAsn1(byte[] c1c3c2) throws IOException { byte[] c1 = Arrays.copyOfRange(c1c3c2, 0, C1_LEN); byte[] c3 = Arrays.copyOfRange(c1c3c2, C1_LEN, C1_LEN + C3_LEN); byte[] c2 = Arrays.copyOfRange(c1c3c2, C1_LEN + C3_LEN, c1c3c2.length); byte[] c1X = Arrays.copyOfRange(c1, 1, 33); byte[] c1Y = Arrays.copyOfRange(c1, 33, 65); BigInteger r = new BigInteger(1, c1X); BigInteger s = new BigInteger(1, c1Y); ASN1Integer x = new ASN1Integer(r); ASN1Integer y = new ASN1Integer(s); DEROctetString derDig = new DEROctetString(c3); DEROctetString derEnc = new DEROctetString(c2); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(x); v.add(y); v.add(derDig); v.add(derEnc); DERSequence seq = new DERSequence(v); return seq.getEncoded(ASN1Encoding.DER); } /** * 将ASN1格式转成c1c3c2 */ public static byte[] changeAsn1ToC1C3C2(byte[] asn1) throws IOException { ASN1InputStream aIn = new ASN1InputStream(asn1); ASN1Sequence seq = (ASN1Sequence) aIn.readObject(); BigInteger x = ASN1Integer.getInstance(seq.getObjectAt(0)).getValue(); BigInteger y = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue(); byte[] c3 = ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets(); byte[] c2 = ASN1OctetString.getInstance(seq.getObjectAt(3)).getOctets(); ECPoint c1Point = GMNamedCurves.getByName("sm2p256v1").getCurve().createPoint(x, y); byte[] c1 = c1Point.getEncoded(false); return ArrayUtil.addAll(c1, c3, c2); } public static void main(String[] args) throws IOException { //需要加密的明文 String text = "1111"; //创建sm2 对象 SM2 sm2 = SmUtil.sm2(); //生成公钥 byte[] publicKey = ((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false); //生成私钥 byte[] privateKey = BCUtil.encodeECPrivateKey(sm2.getPrivateKey()); //打印当前的公私秘钥 System.out.println("公钥: " + HexUtil.encodeHexStr(publicKey)); System.out.println("私钥: " + HexUtil.encodeHexStr(privateKey)); SM2 sm2Test = SmUtil.sm2(privateKey, publicKey); byte[] encrypt = sm2Test.encrypt(text, KeyType.PublicKey); byte[] bytes = changeC1C3C2ToAsn1(encrypt); String encryptData = Base64.encode(bytes); System.out.println("加密后:"+encryptData); byte[] asn1 = Base64.decode(encryptData); byte[] c1c3c2 = changeAsn1ToC1C3C2(asn1); byte[] decryptData = sm2Test.decrypt(c1c3c2, KeyType.PrivateKey); System.out.println("解密后:"+new String(decryptData)); byte[] sign = sm2Test.sign(text.getBytes()); String signText = Base64.encode(sign); System.out.println("签名:"+ signText); boolean verify = sm2Test.verify(text.getBytes(), Base64.decode(signText)); System.out.println("验签结果::"+ verify); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。