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;
}
}