package com.nanjing.water.common.util;
|
|
import org.bouncycastle.crypto.CipherParameters;
|
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
import org.bouncycastle.crypto.params.ParametersWithRandom;
|
import org.bouncycastle.crypto.signers.SM2Signer;
|
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
import org.springframework.util.Base64Utils;
|
|
import java.nio.charset.Charset;
|
import java.nio.charset.StandardCharsets;
|
import java.security.*;
|
import java.security.spec.*;
|
|
public class SM2Util {
|
/**
|
* 要生成的EC域参数的标准名称
|
*/
|
private static final String STANDARD_NAME = "sm2p256v1";
|
/**
|
* 算法
|
*/
|
private static final String ALGORITHM = "EC";
|
/**
|
* 字符编码
|
*/
|
private static final Charset CHARSET = StandardCharsets.UTF_8;
|
|
/**
|
* 生成密钥对
|
*
|
* @return 密钥对
|
*/
|
private static KeyPair generateSm2KeyPair() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
//使用标准名称创建EC参数生成的参数规范
|
final ECGenParameterSpec sm2Spec = new ECGenParameterSpec(STANDARD_NAME);
|
|
// 获取一个椭圆曲线类型的密钥对生成器
|
final KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM, new BouncyCastleProvider());
|
|
kpg.initialize(sm2Spec, new SecureRandom());
|
// 通过密钥生成器生成密钥对
|
return kpg.generateKeyPair();
|
}
|
|
/**
|
* 生成密钥对
|
*
|
* @return 密钥对
|
*/
|
public static String[] genKeyPair() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
KeyPair keyPair = generateSm2KeyPair();
|
PrivateKey privateKey = keyPair.getPrivate();
|
PublicKey publicKey = keyPair.getPublic();
|
return new String[]{
|
Base64Utils.encodeToString(privateKey.getEncoded()),
|
Base64Utils.encodeToString(publicKey.getEncoded())
|
};
|
}
|
|
/**
|
* 私钥转换为 {@link ECPrivateKeyParameters}
|
*
|
* @param key 私钥
|
* @return 私钥{@link ECPrivateKeyParameters}
|
*/
|
private static ECPrivateKeyParameters privateKeyToParams(byte[] key) throws InvalidKeyException, InvalidKeySpecException, NoSuchAlgorithmException {
|
KeySpec keySpec = new PKCS8EncodedKeySpec(key);
|
PrivateKey privateKey = getKeyFactory().generatePrivate(keySpec);
|
;
|
return (ECPrivateKeyParameters) ECUtil.generatePrivateKeyParameter(privateKey);
|
}
|
|
/**
|
* 公钥转换为 {@link ECPublicKeyParameters}
|
*
|
* @param key 公钥
|
* @return 公钥{@link ECPublicKeyParameters}
|
*/
|
private static ECPublicKeyParameters publicKeyToParams(byte[] key) throws InvalidKeyException, InvalidKeySpecException, NoSuchAlgorithmException {
|
KeySpec keySpec = new X509EncodedKeySpec(key);
|
PublicKey publicKey = getKeyFactory().generatePublic(keySpec);
|
return (ECPublicKeyParameters) ECUtil.generatePublicKeyParameter(publicKey);
|
}
|
|
/**
|
* 获取{@link KeyFactory}
|
*
|
* @return {@link KeyFactory}
|
*/
|
private static KeyFactory getKeyFactory() throws NoSuchAlgorithmException {
|
final Provider provider = new BouncyCastleProvider();
|
return KeyFactory.getInstance(ALGORITHM, provider);
|
}
|
|
/**
|
* 签名
|
*
|
* @param content 原始串
|
* @param priKey 私钥
|
* @return 签名
|
*/
|
public static String sign(String content, String priKey) throws Exception {
|
byte[] data = content.getBytes(CHARSET);
|
byte[] privateKey = Base64Utils.decode(priKey.getBytes(CHARSET));
|
|
SM2Signer signer = new SM2Signer();
|
CipherParameters param = new ParametersWithRandom(privateKeyToParams(privateKey));
|
signer.init(true, param);
|
signer.update(data, 0, data.length);
|
|
byte[] buffer = signer.generateSignature();
|
|
return Base64Utils.encodeToString(buffer);
|
}
|
|
/**
|
* 用公钥检验数字签名的合法性
|
*
|
* @param content 原始串
|
* @param sign 待验证签名
|
* @param publicKey 私钥
|
* @return 是否验证通过
|
*/
|
public static boolean verify(String content, String sign, String publicKey) throws Exception {
|
byte[] data = content.getBytes(CHARSET);
|
byte[] signBuffer = Base64Utils.decodeFromString(sign);
|
byte[] keyBuffer = Base64Utils.decodeFromString(publicKey);
|
|
SM2Signer signer = new SM2Signer();
|
CipherParameters param = publicKeyToParams(keyBuffer);
|
signer.init(false, param);
|
signer.update(data, 0, data.length);
|
return signer.verifySignature(signBuffer);
|
}
|
|
|
|
// public static void main(String[] args) {
|
// Security.addProvider(new BouncyCastleProvider());
|
//
|
// try {
|
// // 生成密钥对
|
// String[] keyPair = SM2Util.genKeyPair();
|
// String privateKey = keyPair[0];
|
// String publicKey = keyPair[1];
|
//
|
// // 对消息进行签名
|
// String message = "你好,世界!";
|
// String signature = SM2Util.sign(message, privateKey);
|
// System.out.println("生成的签名: " + signature);
|
//
|
// // 验证签名
|
// boolean isValid = SM2Util.verify(message, signature, publicKey);
|
// System.out.println("签名验证结果: " + isValid);
|
// } catch (Exception e) {
|
// e.printStackTrace();
|
// }
|
// }
|
}
|