diff --git a/kernel-d-security/security-sdk-guomi/src/main/java/cn/stylefeng/roses/kernel/security/guomi/GuomiUtil.java b/kernel-d-security/security-sdk-guomi/src/main/java/cn/stylefeng/roses/kernel/security/guomi/GuomiUtil.java index 96046ad0b..f4d8e8f6f 100644 --- a/kernel-d-security/security-sdk-guomi/src/main/java/cn/stylefeng/roses/kernel/security/guomi/GuomiUtil.java +++ b/kernel-d-security/security-sdk-guomi/src/main/java/cn/stylefeng/roses/kernel/security/guomi/GuomiUtil.java @@ -1,10 +1,16 @@ package cn.stylefeng.roses.kernel.security.guomi; +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.HexUtil; +import cn.hutool.crypto.BCUtil; import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.SM2; import cn.hutool.crypto.symmetric.SM4; import cn.stylefeng.roses.kernel.security.guomi.expander.GuomiConfigExpander; +import org.bouncycastle.crypto.engines.SM2Engine; +import org.bouncycastle.crypto.params.ECPrivateKeyParameters; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; import java.nio.charset.StandardCharsets; @@ -27,10 +33,25 @@ public class GuomiUtil { * @since 2024/6/25 10:50 */ public static String sm2EncryptWithPublic(String text) { - String sm2PrivateKey = GuomiConfigExpander.getSM2PrivateKey(); - String sm2PublicKey = GuomiConfigExpander.getSM2PublicKey(); - SM2 sm2 = SmUtil.sm2(sm2PrivateKey, sm2PublicKey); - return sm2.encryptBase64(text, StandardCharsets.UTF_8, KeyType.PublicKey); + // 获取公钥字符串,应该是16进制,130位 + String publicKey = GuomiConfigExpander.getSM2PublicKey(); + + // 如果是130位的话,去掉前面的04 + if (publicKey.length() == 130) { + publicKey = publicKey.substring(2); + } + + // 16进制的公钥转换为ECPublicKeyParameters + String xhex = publicKey.substring(0, 64); + String yhex = publicKey.substring(64, 128); + ECPublicKeyParameters ecPublicKeyParameters = BCUtil.toSm2Params(xhex, yhex); + + //创建sm2 对象 + SM2 sm2 = new SM2(null, ecPublicKeyParameters); + sm2.usePlainEncoding(); + sm2.setMode(SM2Engine.Mode.C1C3C2); + String hex = sm2.encryptHex(text, KeyType.PublicKey).substring(2); + return Base64.encode(HexUtil.decodeHex(hex)); } /** @@ -41,9 +62,11 @@ public class GuomiUtil { */ public static String sm2DecryptWithPrivate(String encryptedStr) { String sm2PrivateKey = GuomiConfigExpander.getSM2PrivateKey(); - String sm2PublicKey = GuomiConfigExpander.getSM2PublicKey(); - SM2 sm2 = SmUtil.sm2(sm2PrivateKey, sm2PublicKey); - return sm2.decryptStr(encryptedStr, KeyType.PrivateKey, StandardCharsets.UTF_8); + ECPrivateKeyParameters privateKeyParameters = BCUtil.toSm2Params(sm2PrivateKey); + SM2 sm2 = new SM2(privateKeyParameters, null); + sm2.usePlainEncoding(); + sm2.setMode(SM2Engine.Mode.C1C3C2); + return sm2.decryptStr("04" + HexUtil.encodeHexStr(Base64.decode(encryptedStr)), KeyType.PrivateKey); } /** @@ -80,6 +103,4 @@ public class GuomiUtil { return sm4.decryptStr(encryptedStr, StandardCharsets.UTF_8); } - - } diff --git a/kernel-d-security/security-sdk-guomi/src/main/java/cn/stylefeng/roses/kernel/security/guomi/config/GuomiConfigStrategyImpl.java b/kernel-d-security/security-sdk-guomi/src/main/java/cn/stylefeng/roses/kernel/security/guomi/config/GuomiConfigStrategyImpl.java index 1c71c4a5d..4b7f3643f 100644 --- a/kernel-d-security/security-sdk-guomi/src/main/java/cn/stylefeng/roses/kernel/security/guomi/config/GuomiConfigStrategyImpl.java +++ b/kernel-d-security/security-sdk-guomi/src/main/java/cn/stylefeng/roses/kernel/security/guomi/config/GuomiConfigStrategyImpl.java @@ -1,15 +1,18 @@ package cn.stylefeng.roses.kernel.security.guomi.config; import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.HexUtil; +import cn.hutool.crypto.BCUtil; import cn.hutool.crypto.KeyUtil; -import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.SmUtil; +import cn.hutool.crypto.asymmetric.SM2; import cn.hutool.crypto.symmetric.SM4; import cn.stylefeng.roses.kernel.config.api.ConfigInitStrategyApi; import cn.stylefeng.roses.kernel.config.api.pojo.ConfigInitItem; import cn.stylefeng.roses.kernel.security.guomi.constants.GuomiConstants; +import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.springframework.stereotype.Component; -import java.security.KeyPair; import java.util.ArrayList; import java.util.List; @@ -38,12 +41,12 @@ public class GuomiConfigStrategyImpl implements ConfigInitStrategyApi { ArrayList configInitItems = new ArrayList<>(); // 生成一个公钥私钥对 - KeyPair pair = SecureUtil.generateKeyPair("SM2"); - byte[] publicKey = pair.getPublic().getEncoded(); - configInitItems.add(new ConfigInitItem("国密算法SM2-公钥", GuomiConstants.GUOMI_SM2_PUBLIC_KEY, Base64.encode(publicKey), "国密SM2非对称加密,公钥生成")); + SM2 sm2 = SmUtil.sm2(); + String hutoolPrivateKeyHex = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(sm2.getPrivateKey())); + String hutoolPublicKeyHex = HexUtil.encodeHexStr(((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false)); - byte[] privateKey = pair.getPrivate().getEncoded(); - configInitItems.add(new ConfigInitItem("国密算法SM2-私钥", GuomiConstants.GUOMI_SM2_PRIVATE_KEY, Base64.encode(privateKey), "国密SM2非对称加密,私钥生成")); + configInitItems.add(new ConfigInitItem("国密算法SM2-公钥", GuomiConstants.GUOMI_SM2_PUBLIC_KEY, hutoolPublicKeyHex, "国密SM2非对称加密,公钥生成")); + configInitItems.add(new ConfigInitItem("国密算法SM2-私钥", GuomiConstants.GUOMI_SM2_PRIVATE_KEY, hutoolPrivateKeyHex, "国密SM2非对称加密,私钥生成")); // 生成SM4的对称加密的秘钥 byte[] sm4Key = KeyUtil.generateKey(SM4.ALGORITHM_NAME, 128).getEncoded();