|
|
@@ -0,0 +1,109 @@
|
|
|
+package com.ruoyi.common.utils;
|
|
|
+
|
|
|
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import java.security.*;
|
|
|
+import java.security.spec.PKCS8EncodedKeySpec;
|
|
|
+import java.security.spec.X509EncodedKeySpec;
|
|
|
+import java.util.Base64;
|
|
|
+
|
|
|
+/**
|
|
|
+ * SM2非对称加密工具类 - 兼容版本
|
|
|
+ */
|
|
|
+@Component
|
|
|
+public class SM2Util {
|
|
|
+
|
|
|
+ static {
|
|
|
+ Security.addProvider(new BouncyCastleProvider());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成SM2密钥对
|
|
|
+ */
|
|
|
+ public static KeyPair generateKeyPair() {
|
|
|
+ try {
|
|
|
+ // 使用标准的KeyPairGenerator
|
|
|
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");
|
|
|
+
|
|
|
+ // 使用SM2参数
|
|
|
+ keyPairGenerator.initialize(256); // SM2使用256位
|
|
|
+
|
|
|
+ return keyPairGenerator.generateKeyPair();
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException("生成SM2密钥对失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用私钥对数据进行签名
|
|
|
+ */
|
|
|
+ public static String sign(byte[] data, PrivateKey privateKey) {
|
|
|
+ try {
|
|
|
+ Signature signature = Signature.getInstance("SM3withSM2", "BC");
|
|
|
+ signature.initSign(privateKey);
|
|
|
+ signature.update(data);
|
|
|
+ byte[] signBytes = signature.sign();
|
|
|
+ return Base64.getEncoder().encodeToString(signBytes);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException("SM2签名失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用公钥验证签名
|
|
|
+ */
|
|
|
+ public static boolean verify(byte[] data, String signature, PublicKey publicKey) {
|
|
|
+ try {
|
|
|
+ Signature verifier = Signature.getInstance("SM3withSM2", "BC");
|
|
|
+ verifier.initVerify(publicKey);
|
|
|
+ verifier.update(data);
|
|
|
+ byte[] signatureBytes = Base64.getDecoder().decode(signature);
|
|
|
+ return verifier.verify(signatureBytes);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException("SM2验签失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从Base64字符串加载私钥
|
|
|
+ */
|
|
|
+ public static PrivateKey loadPrivateKey(String base64PrivateKey) {
|
|
|
+ try {
|
|
|
+ byte[] keyBytes = Base64.getDecoder().decode(base64PrivateKey);
|
|
|
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
|
|
|
+ return keyFactory.generatePrivate(keySpec);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException("加载SM2私钥失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从Base64字符串加载公钥
|
|
|
+ */
|
|
|
+ public static PublicKey loadPublicKey(String base64PublicKey) {
|
|
|
+ try {
|
|
|
+ byte[] keyBytes = Base64.getDecoder().decode(base64PublicKey);
|
|
|
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
|
|
|
+ return keyFactory.generatePublic(keySpec);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException("加载SM2公钥失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将私钥转换为Base64字符串
|
|
|
+ */
|
|
|
+ public static String privateKeyToString(PrivateKey privateKey) {
|
|
|
+ return Base64.getEncoder().encodeToString(privateKey.getEncoded());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将公钥转换为Base64字符串
|
|
|
+ */
|
|
|
+ public static String publicKeyToString(PublicKey publicKey) {
|
|
|
+ return Base64.getEncoder().encodeToString(publicKey.getEncoded());
|
|
|
+ }
|
|
|
+}
|