JAVA bouncycastle实现SM2算法(国密2)
package com.blcase.common.utils.sm;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.*;
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 org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
public class SM2Util {
public String encrypt(String publicKey, String data) {
X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(publicKey));
ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);
SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
sm2Engine.init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));
byte[] arrayOfBytes = null;
try {
byte[] in = data.getBytes();
arrayOfBytes = sm2Engine.processBlock(in, 0, in.length);
} catch (Exception e) {
System.out.println("SM2加密时出现异常:"+e.getMessage());
}
return Hex.toHexString(arrayOfBytes);
}
public String decrypt(String privateKey, String cipherData) {
if (!cipherData.startsWith("04")){
cipherData = "04" + cipherData;
}
byte[] cipherDataByte = Hex.decode(cipherData);
X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
BigInteger privateKeyD = new BigInteger(privateKey, 16);
ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
sm2Engine.init(false, privateKeyParameters);
String result = "";
try {
byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
return new String(arrayOfBytes);
} catch (Exception e) {
System.out.println("SM2解密时出现异常:"+e.getMessage());
}
return result;
}
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
String M="encryption standard";
SM2Util sm2 = new SM2Util();
final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
kpg.initialize(sm2Spec);
KeyPair keyPair = kpg.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
BCECPublicKey p=(BCECPublicKey)publicKey;
System.out.print("\n公钥:"+Hex.toHexString(p.getQ().getEncoded(false)));
PrivateKey privateKey = keyPair.getPrivate();
BCECPrivateKey s=(BCECPrivateKey)privateKey;
System.out.print("\n私钥:"+Hex.toHexString(s.getD().toByteArray()));
String data = sm2.encrypt(Hex.toHexString(p.getQ().getEncoded(false)),M);
System.out.println("\n加密字符串:"+data);
String text=sm2.decrypt(Hex.toHexString(s.getD().toByteArray()),data);
System.out.println("\n解密:"+text);
}
}