135 lines
5.3 KiB
Java
135 lines
5.3 KiB
Java
package com.sunyard.cisd.device.tool;
|
|
|
|
import org.bouncycastle.jce.ECNamedCurveTable;
|
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
import org.bouncycastle.jce.spec.ECParameterSpec;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.security.*;
|
|
import java.security.spec.PKCS8EncodedKeySpec;
|
|
import java.security.spec.X509EncodedKeySpec;
|
|
import java.util.Base64;
|
|
|
|
public class SM2Util {
|
|
private static final String ALGORITHM = "EC";
|
|
private static final String PROVIDER = "BC";
|
|
private static final String CURVE_NAME = "sm2p256v1";
|
|
private static final String SIGNATURE_ALGORITHM = "SM3withSM2";
|
|
|
|
static {
|
|
Security.addProvider(new BouncyCastleProvider());
|
|
}
|
|
|
|
public static byte[] sign(byte[] data, PrivateKey privateKey) throws Exception {
|
|
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM, PROVIDER);
|
|
signature.initSign(privateKey);
|
|
signature.update(data);
|
|
return signature.sign();
|
|
}
|
|
|
|
public static boolean verify(byte[] data, byte[] sign, PublicKey publicKey) throws Exception {
|
|
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM, PROVIDER);
|
|
signature.initVerify(publicKey);
|
|
signature.update(data);
|
|
return signature.verify(sign);
|
|
}
|
|
|
|
public static byte[] sign(byte[] data, String privateKeyFilePath) throws Exception {
|
|
PrivateKey privateKey = loadPrivateKey(privateKeyFilePath);
|
|
return sign(data, privateKey);
|
|
}
|
|
|
|
public static boolean verify(byte[] data, byte[] sign, String publicKeyFilePath) throws Exception {
|
|
PublicKey publicKey = loadPublicKey(publicKeyFilePath);
|
|
return verify(data, sign, publicKey);
|
|
}
|
|
|
|
public static PrivateKey loadPrivateKey(String filePath) throws Exception {
|
|
InputStream inputStream = SM2Util.class.getResourceAsStream(filePath);
|
|
if (inputStream == null) {
|
|
throw new IllegalArgumentException("Private key file not found: " + filePath);
|
|
}
|
|
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
|
StringBuilder keyBuilder = new StringBuilder();
|
|
String line;
|
|
while ((line = reader.readLine()) != null) {
|
|
if (!line.startsWith("-----")) {
|
|
keyBuilder.append(line.trim());
|
|
}
|
|
}
|
|
reader.close();
|
|
|
|
String keyBase64 = keyBuilder.toString();
|
|
byte[] keyBytes = Base64.getDecoder().decode(keyBase64);
|
|
|
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
|
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM, PROVIDER);
|
|
return keyFactory.generatePrivate(keySpec);
|
|
}
|
|
|
|
public static PublicKey loadPublicKey(String filePath) throws Exception {
|
|
InputStream inputStream = SM2Util.class.getResourceAsStream(filePath);
|
|
if (inputStream == null) {
|
|
throw new IllegalArgumentException("Public key file not found: " + filePath);
|
|
}
|
|
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
|
StringBuilder keyBuilder = new StringBuilder();
|
|
String line;
|
|
while ((line = reader.readLine()) != null) {
|
|
if (!line.startsWith("-----")) {
|
|
keyBuilder.append(line.trim());
|
|
}
|
|
}
|
|
reader.close();
|
|
|
|
String keyBase64 = keyBuilder.toString();
|
|
byte[] keyBytes = Base64.getDecoder().decode(keyBase64);
|
|
|
|
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
|
|
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM, PROVIDER);
|
|
return keyFactory.generatePublic(keySpec);
|
|
}
|
|
|
|
public static KeyPair generateKeyPair() throws Exception {
|
|
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM, PROVIDER);
|
|
ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(CURVE_NAME);
|
|
keyPairGenerator.initialize(ecSpec, new SecureRandom());
|
|
return keyPairGenerator.generateKeyPair();
|
|
}
|
|
|
|
public static String privateKeyToPEM(PrivateKey privateKey) {
|
|
byte[] encoded = privateKey.getEncoded();
|
|
String base64 = Base64.getEncoder().encodeToString(encoded);
|
|
StringBuilder pem = new StringBuilder();
|
|
pem.append("-----BEGIN PRIVATE KEY-----\n");
|
|
int index = 0;
|
|
while (index < base64.length()) {
|
|
pem.append(base64.substring(index, Math.min(index + 64, base64.length())));
|
|
pem.append("\n");
|
|
index += 64;
|
|
}
|
|
pem.append("-----END PRIVATE KEY-----\n");
|
|
return pem.toString();
|
|
}
|
|
|
|
public static String publicKeyToPEM(PublicKey publicKey) {
|
|
byte[] encoded = publicKey.getEncoded();
|
|
String base64 = Base64.getEncoder().encodeToString(encoded);
|
|
StringBuilder pem = new StringBuilder();
|
|
pem.append("-----BEGIN PUBLIC KEY-----\n");
|
|
int index = 0;
|
|
while (index < base64.length()) {
|
|
pem.append(base64.substring(index, Math.min(index + 64, base64.length())));
|
|
pem.append("\n");
|
|
index += 64;
|
|
}
|
|
pem.append("-----END PUBLIC KEY-----\n");
|
|
return pem.toString();
|
|
}
|
|
}
|