import com.itextpdf.text.pdf.security.ExternalDigest;
 import org.bouncycastle.asn1.gm.GMNamedCurves;
 import org.bouncycastle.asn1.x9.X9ECParameters;
 import org.bouncycastle.crypto.CipherParameters;
 import org.bouncycastle.crypto.Digest;
 import org.bouncycastle.crypto.digests.SM3Digest;
 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.jcajce.provider.asymmetric.ec.GMCipherSpi;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.bouncycastle.jce.spec.ECParameterSpec;
 import org.bouncycastle.jce.spec.ECPrivateKeySpec;
 import org.bouncycastle.jce.spec.ECPublicKeySpec;
 import org.bouncycastle.math.ec.ECCurve;
 import org.bouncycastle.math.ec.ECPoint;
 import org.bouncycastle.util.BigIntegers;
 import org.bouncycastle.util.encoders.Hex;
import javax.crypto.Cipher;
 import java.math.BigInteger;
 import java.security.*;
 import java.security.interfaces.ECPrivateKey;
 import java.security.interfaces.ECPublicKey;
 import java.security.spec.ECGenParameterSpec;
 import java.util.Base64;
/**
 * 
SM2算法
 */
 public class SM2Digest {
public static MessageDigest GETSM2ENCRYPTION() throws Exception {
 BouncyCastleProvider provider = new BouncyCastleProvider(); // 获取椭圆曲线相关生成参数规格 
ECGenParameterSpec genParameterSpec = new ECGenParameterSpec("sm2p256v1"); // 
获取一个椭圆曲线类型的密钥对生成器 KeyPairGenerator keyPairGenerator = 
KeyPairGenerator.getInstance("EC", provider); // 使用SM2的算法区域初始化密钥生成器 
keyPairGenerator.initialize(genParameterSpec, new SecureRandom()); // 生成密钥对 
KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 生成的私钥 BCECPrivateKey 
privateKey = (BCECPrivateKey) keyPair.getPrivate(); // 生成的公钥 BCECPublicKey 
publicKey = (BCECPublicKey) keyPair.getPublic(); // 拿到32字节的私钥HEX 
System.out.println("privateKEY:" + privateKey); System.out.println("Private 
Key: " + privateKey.getD().toString(16)); // true 代表压缩密钥,以02、03开头,长度为33字节 // 
false 代表未压缩,以04开头,长度为65字节 System.out.println("publicKey:" + publicKey); 
System.out.println("Public Key: " + 
Hex.encode(publicKey.getQ().getEncoded(true))); 
System.out.println("--------------------------生成现有公私钥-------------------------------------"); 
return null; 
}
static String SM2_CURVE_NAME = “sm2p256v1”;
public static void main(String[] args) throws Exception {
 // GETSM2ENCRYPTION();
 //私钥
 String prvKey = 
“b5afc784d10ff0890634bf49dc1d9c46e63de0b90c489752aec0d518ac4aa9b3”;
 //公钥坐标
 String x = “ed771635c8344a3f0f715e02fcd44a0f4a771611c07bbfd941e9d8de2b58a35d”;
 String y = “a57a2eb3ef4aca94dab8e9d4237f63f87e5043ba78847cb175e5ed3a8f26c6d9”;
 String info = "测试公私钥匙加密解密"; byte[] data = info.getBytes(); SM2Digest sm2 = 
new SM2Digest(); ECDomainParameters domain = sm2.getDomain(); SM2Engine engine 
= sm2.getSM2Engine(); //公钥加密 CipherParameters pubKeyParameters = 
sm2.getPubKey(x, y, domain); engine.init(true, pubKeyParameters); byte[] 
encData = engine.processBlock(data, 0, data.length); 
System.out.println("加密后内容:" + Hex.toHexString(encData)); //私钥解密 
CipherParameters PrivateKey = sm2.getPrvKey(prvKey, domain); engine.init(false, 
PrivateKey); byte[] decData = engine.processBlock(encData, 0, encData.length); 
System.out.println("解密后内容:" + new String(decData)); 
}
/**
 * 构造私钥对象
 * 
 * @param prvKey
 * @return
 */
 public CipherParameters getPrvKey(String prvKey, ECDomainParameters domain) {
 BigInteger prvKeyData = BigIntegers.fromUnsignedByteArray(Hex.decode(prvKey));
 ECPrivateKeyParameters PrivateKey = new ECPrivateKeyParameters(prvKeyData, 
domain);
 return PrivateKey;
 } 
/**
 * 构造公钥对象
 * 
 * @param x
 * @param y
 * @param domain
 * @return
 */
 public CipherParameters getPubKey(String x, String y, ECDomainParameters 
domain) {
 ECCurve curve = domain.getCurve();
 ECPoint point = 
curve.createPoint(BigIntegers.fromUnsignedByteArray(Hex.decode(x)), 
BigIntegers.fromUnsignedByteArray(Hex.decode(y)));
 ECPublicKeyParameters PublicKey = new ECPublicKeyParameters(point, domain);
 CipherParameters pubKeyParameters = new ParametersWithRandom(PublicKey);
 return pubKeyParameters;
 } 
public SM2Engine getSM2Engine() {
 Digest digest = new SM3Digest();
 SM2Engine engine = new SM2Engine(digest, SM2Engine.Mode.C1C3C2);
 return engine;
 }
public ECDomainParameters getDomain() {
 X9ECParameters x9ECParameters = GMNamedCurves.getByName(SM2_CURVE_NAME);
 ECDomainParameters domain = new ECDomainParameters(
 x9ECParameters.getCurve(),
 x9ECParameters.getG(),
 x9ECParameters.getN(),
 x9ECParameters.getH()
 );
 return domain;
 }
}