SMUtil
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.File;
import java.io.FileInputStream;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
public class SMUtil {
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* 摘要
*
* @param src 原文
*/
/*public static String generateSM3Hash(String src) {
byte[] md = new byte[32];
byte[] msg1 = src.getBytes();
SM3Digest sm3 = new SM3Digest();
sm3.update(msg1, 0, msg1.length);
sm3.doFinal(md, 0);
String s = new String(Hex.encode(md));
return s.toUpperCase();
}*/
/**
* 加签
*
* @param toSignText 原文
*/
public static String signatureTo(String privateKey, String toSignText, String charset) throws Exception {
// 生成SM2sign with sm3 签名验签算法实例
Signature signature = Signature.getInstance("SM3withSm2", new BouncyCastleProvider());
// 签名需要使用私钥,使用私钥 初始化签名实例
signature.initSign(getPrivateKey(privateKey));
// 签名原文
byte[] plainText = toSignText.getBytes(charset);
// 写入签名原文到算法中
signature.update(plainText);
// 计算签名值
byte[] bytes = signature.sign();
byte[] signatureValue = Base64.encodeBase64(bytes);
//String s = byteToHex(signatureValue);
return new String(signatureValue);
}
/**
* 验签
*
* @param publicKeyPath 公钥路径
* @param toVerifyText 原文
* @param signatureValue 加签后得到的签文
*/
public static int signatureGet(String publicKeyPath, String toVerifyText, String signatureValue, String charset) throws Exception {
publicKeyPath = System.getProperty("ConfigPath") + File.separator + publicKeyPath;
//byte[] signatureByte = hexStringToBytes(signatureValue);
byte[] signatureByte = Base64.decodeBase64(signatureValue.getBytes());
byte[] verifyText = toVerifyText.getBytes();
// 生成SM2sign with sm3 签名验签算法实例
Signature signature = Signature.getInstance("SM3withSm2", new BouncyCastleProvider());
//通过地址获取公钥
PublicKey publicKey = SMUtil.getPublicKeyFromX509File(new File(publicKeyPath));
// 签名需要使用公钥,使用公钥 初始化签名实例
signature.initVerify(publicKey);
// 写入待验签的签名原文到算法中
signature.update(verifyText);
if (signature.verify(signatureByte)) {
return 1;
} else {
return 0;
}
}
//读取证书中的公钥
public static PublicKey getPublicKeyFromX509File(File file) {
try {
CertificateFactory cf = CertificateFactory.getInstance("x.509", "BC");
FileInputStream in = new FileInputStream(file);
X509Certificate x509 = (X509Certificate) cf.generateCertificate(in);
return x509.getPublicKey();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//私钥
public static PrivateKey getPrivateKey(String hexPri) throws Exception {
final BouncyCastleProvider bc = new BouncyCastleProvider();
byte[] encPri = hexStringToBytes(hexPri);
KeyFactory keyFact = KeyFactory.getInstance("EC", bc);
// 根据采用的编码结构反序列化公私钥
PrivateKey pri = keyFact.generatePrivate(new PKCS8EncodedKeySpec(encPri));
return pri;
}
/**
* 对称秘钥加密(ECB)
*
* @param text 原文
*/
public static String SM4EncForECB(String key, String text, String charset) throws Exception {
return SM4.encryptBase64Str(text.getBytes(charset), hexStringToBytes(key), charset);
}
/**
* 对称秘钥解密(ECB)
*
* @param text 加密后的内容
*/
public static String SM4DecForECB(String key, String text, String charset) throws Exception {
return SM4.decryptBase64(Base64.decodeBase64(text), hexStringToBytes(key), charset);
}
/**
* Convert hex string to byte[]
*
* @param hexString the hex string
* @return byte[]
*/
public static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
public static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}}
查看6道真题和解析
