diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/config/SecureConfiguration.java b/blade-core-secure/src/main/java/org/springblade/core/secure/config/SecureConfiguration.java index be228c8..baba9cc 100644 --- a/blade-core-secure/src/main/java/org/springblade/core/secure/config/SecureConfiguration.java +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/config/SecureConfiguration.java @@ -20,6 +20,7 @@ import lombok.AllArgsConstructor; import org.springblade.core.secure.aspect.AuthAspect; import org.springblade.core.secure.interceptor.ClientInterceptor; import org.springblade.core.secure.interceptor.SecureInterceptor; +import org.springblade.core.secure.props.BladeAuthProperties; import org.springblade.core.secure.props.BladeSecureProperties; import org.springblade.core.secure.props.BladeTokenProperties; import org.springblade.core.secure.provider.ClientDetailsServiceImpl; @@ -42,7 +43,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Order @AutoConfiguration @AllArgsConstructor -@EnableConfigurationProperties({BladeSecureProperties.class, BladeTokenProperties.class}) +@EnableConfigurationProperties({BladeAuthProperties.class, BladeSecureProperties.class, BladeTokenProperties.class}) public class SecureConfiguration implements WebMvcConfigurer { private final SecureRegistry secureRegistry; diff --git a/blade-core-secure/src/main/java/org/springblade/core/secure/props/BladeAuthProperties.java b/blade-core-secure/src/main/java/org/springblade/core/secure/props/BladeAuthProperties.java new file mode 100644 index 0000000..2ed670a --- /dev/null +++ b/blade-core-secure/src/main/java/org/springblade/core/secure/props/BladeAuthProperties.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). + *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springblade.core.secure.props;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * secure放行额外配置
+ *
+ * @author Chill
+ */
+@Data
+@ConfigurationProperties("blade.auth")
+public class BladeAuthProperties {
+
+ /**
+ * sm2公钥
+ */
+ private String publicKey;
+
+ /**
+ * sm2私钥
+ */
+ private String privateKey;
+
+}
diff --git a/blade-core-tool/pom.xml b/blade-core-tool/pom.xml
index eb787f4..2d11e53 100644
--- a/blade-core-tool/pom.xml
+++ b/blade-core-tool/pom.xml
@@ -53,6 +53,11 @@
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springblade.core.tool.utils;
+
+import org.bouncycastle.asn1.gm.GMNamedCurves;
+import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import org.bouncycastle.crypto.engines.SM2Engine;
+import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
+import org.bouncycastle.crypto.params.*;
+import org.bouncycastle.crypto.signers.SM2Signer;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.util.encoders.Hex;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+import java.security.Security;
+
+/**
+ * SM2加密、解密、签名和验证工具类。
+ *
+ * @author BladeX
+ */
+public class SM2Util {
+ static {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ private static final ECDomainParameters DOMAIN_PARAMS;
+
+ static {
+ X9ECParameters spec = GMNamedCurves.getByName("sm2p256v1");
+ DOMAIN_PARAMS = new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN(), spec.getH());
+ }
+
+ /**
+ * 生成SM2密钥对。
+ *
+ * @return 密钥对(公钥和私钥)
+ */
+ public static AsymmetricCipherKeyPair generateKeyPair() {
+ ECKeyPairGenerator generator = new ECKeyPairGenerator();
+ generator.init(new ECKeyGenerationParameters(DOMAIN_PARAMS, new SecureRandom()));
+ return generator.generateKeyPair();
+ }
+
+
+ /**
+ * 使用SM2算法加密文本。
+ *
+ * @param input 文本数据
+ * @param publicKey 公钥
+ * @return 加密后的数据
+ */
+ public static byte[] encrypt(String input, String publicKey) {
+ return encrypt(input, stringToPublicKey(publicKey));
+ }
+
+ /**
+ * 使用SM2算法加密文本。
+ *
+ * @param input 文本数据
+ * @param publicKey 公钥
+ * @return 加密后的数据
+ */
+ public static byte[] encrypt(String input, ECPublicKeyParameters publicKey) {
+ try {
+ SM2Engine engine = new SM2Engine();
+ engine.init(true, new ParametersWithRandom(publicKey, new SecureRandom()));
+ byte[] inputBytes = input.getBytes();
+ return engine.processBlock(inputBytes, 0, inputBytes.length);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 使用SM2算法解密数据。
+ *
+ * @param encrypted 加密的数据
+ * @param privateKey 私钥
+ * @return 解密后的文本
+ */
+ public static String decrypt(String encrypted, String privateKey) {
+ return decrypt(Hex.decode(encrypted), privateKey);
+ }
+
+ /**
+ * 使用SM2算法解密数据。
+ *
+ * @param encrypted 加密的数据
+ * @param privateKey 私钥
+ * @return 解密后的文本
+ */
+ public static String decrypt(byte[] encrypted, String privateKey) {
+ return decrypt(encrypted, stringToPrivateKey(privateKey));
+ }
+
+ /**
+ * 使用SM2算法解密数据。
+ *
+ * @param encrypted 加密的数据
+ * @param privateKey 私钥
+ * @return 解密后的文本
+ */
+ public static String decrypt(byte[] encrypted, ECPrivateKeyParameters privateKey) {
+ try {
+ SM2Engine engine = new SM2Engine();
+ engine.init(false, privateKey);
+ byte[] decryptedBytes = engine.processBlock(encrypted, 0, encrypted.length);
+ return new String(decryptedBytes);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 使用SM2算法进行数据签名。
+ *
+ * @param input 需要签名的数据
+ * @param privateKey 私钥
+ * @return 签名
+ */
+ public static byte[] sign(String input, String privateKey) {
+ return sign(input, stringToPrivateKey(privateKey));
+ }
+
+ /**
+ * 使用SM2算法进行数据签名。
+ *
+ * @param input 需要签名的数据
+ * @param privateKey 私钥
+ * @return 签名
+ */
+ public static byte[] sign(String input, ECPrivateKeyParameters privateKey) {
+ try {
+ SM2Signer signer = new SM2Signer();
+ signer.init(true, new ParametersWithRandom(privateKey, new SecureRandom()));
+ byte[] inputBytes = input.getBytes();
+ signer.update(inputBytes, 0, inputBytes.length);
+ return signer.generateSignature();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 使用SM2算法验证签名。
+ *
+ * @param input 数据
+ * @param signature 签名
+ * @param publicKey 公钥
+ * @return 是否验证成功
+ */
+ public static boolean verify(String input, byte[] signature, String publicKey) {
+ return verify(input, signature, stringToPublicKey(publicKey));
+ }
+
+ /**
+ * 使用SM2算法验证签名。
+ *
+ * @param input 数据
+ * @param signature 签名
+ * @param publicKey 公钥
+ * @return 是否验证成功
+ */
+ public static boolean verify(String input, byte[] signature, ECPublicKeyParameters publicKey) {
+ try {
+ SM2Signer signer = new SM2Signer();
+ signer.init(false, publicKey);
+ byte[] inputBytes = input.getBytes();
+ signer.update(inputBytes, 0, inputBytes.length);
+ return signer.verifySignature(signature);
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * 获取公钥字符串。
+ *
+ * @param keyPair 密钥对
+ * @return 公钥字符串
+ */
+ public static String getPublicKeyString(AsymmetricCipherKeyPair keyPair) {
+ ECPublicKeyParameters ecPublicKeyParameters = (ECPublicKeyParameters) keyPair.getPublic();
+ return Hex.toHexString(ecPublicKeyParameters.getQ().getEncoded(false));
+ }
+
+ /**
+ * 获取私钥字符串。
+ *
+ * @param keyPair 密钥对
+ * @return 私钥字符串
+ */
+ public static String getPrivateKeyString(AsymmetricCipherKeyPair keyPair) {
+ ECPrivateKeyParameters ecPrivateKeyParameters = (ECPrivateKeyParameters) keyPair.getPrivate();
+ return Hex.toHexString(ecPrivateKeyParameters.getD().toByteArray());
+ }
+
+ /**
+ * 从字符串恢复公钥。
+ *
+ * @param data 公钥字符串
+ * @return 公钥
+ */
+ public static ECPublicKeyParameters stringToPublicKey(String data) {
+ return new ECPublicKeyParameters(DOMAIN_PARAMS.getCurve().decodePoint(Hex.decode(data)), DOMAIN_PARAMS);
+ }
+
+ /**
+ * 从字符串恢复私钥。
+ *
+ * @param data 私钥字符串
+ * @return 私钥
+ */
+ public static ECPrivateKeyParameters stringToPrivateKey(String data) {
+ return new ECPrivateKeyParameters(new BigInteger(Hex.decode(data)), DOMAIN_PARAMS);
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index dc5b8f1..18d225a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -379,6 +379,12 @@