diff --git a/continew-starter-core/src/main/java/top/charles7c/continew/starter/core/constant/PropertiesConstants.java b/continew-starter-core/src/main/java/top/charles7c/continew/starter/core/constant/PropertiesConstants.java index 41643267..4fb7dcdc 100644 --- a/continew-starter-core/src/main/java/top/charles7c/continew/starter/core/constant/PropertiesConstants.java +++ b/continew-starter-core/src/main/java/top/charles7c/continew/starter/core/constant/PropertiesConstants.java @@ -52,12 +52,17 @@ public class PropertiesConstants { /** * 安全配置 */ - public static final String SECURITY = CONTINEW_STARTER + ".security"; + public static final String SECURITY = CONTINEW_STARTER + StringConstants.DOT + "security"; /** * 密码编解码配置 */ - public static final String PASSWORD = SECURITY + ".password"; + public static final String PASSWORD = SECURITY + StringConstants.DOT + "password"; + + /** + * 加/解密配置 + */ + public static final String CRYPTO = SECURITY + StringConstants.DOT + "crypto"; /** * Web 配置 diff --git a/continew-starter-dependencies/pom.xml b/continew-starter-dependencies/pom.xml index 9389a0ae..381d88ef 100644 --- a/continew-starter-dependencies/pom.xml +++ b/continew-starter-dependencies/pom.xml @@ -120,6 +120,11 @@ mybatis-plus-spring-boot3-starter ${mybatis-plus.version} + + com.baomidou + mybatis-plus-core + ${mybatis-plus.version} + @@ -382,6 +387,13 @@ ${revision} + + + top.charles7c.continew + continew-starter-security-crypto + ${revision} + + top.charles7c.continew diff --git a/continew-starter-security/continew-starter-security-crypto/pom.xml b/continew-starter-security/continew-starter-security-crypto/pom.xml new file mode 100644 index 00000000..359c6b18 --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + top.charles7c.continew + continew-starter-security + ${revision} + + + continew-starter-security-crypto + ContiNew Starter 安全模块 - 加密 + + + + + cn.hutool + hutool-crypto + + + + + com.baomidou + mybatis-plus-core + + + \ No newline at end of file diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/annotation/FieldEncrypt.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/annotation/FieldEncrypt.java new file mode 100644 index 00000000..46681436 --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/annotation/FieldEncrypt.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 top.charles7c.continew.starter.security.crypto.annotation; + +import top.charles7c.continew.starter.security.crypto.encryptor.IEncryptor; +import top.charles7c.continew.starter.security.crypto.enums.Algorithm; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 字段加/解密注解 + * + * @author Charles7c + * @since 1.4.0 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface FieldEncrypt { + + /** + * 加密/解密算法 + */ + Algorithm value() default Algorithm.AES; + + /** + * 加密/解密处理器 + *

+ * 优先级高于加密/解密算法 + *

+ */ + Class encryptor() default IEncryptor.class; + + /** + * 对称加密算法密钥 + */ + String password() default ""; +} \ No newline at end of file diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/autoconfigure/CryptoAutoConfiguration.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/autoconfigure/CryptoAutoConfiguration.java new file mode 100644 index 00000000..a34e9ad3 --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/autoconfigure/CryptoAutoConfiguration.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 top.charles7c.continew.starter.security.crypto.autoconfigure; + +import jakarta.annotation.PostConstruct; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import top.charles7c.continew.starter.core.constant.PropertiesConstants; +import top.charles7c.continew.starter.security.crypto.core.MyBatisDecryptInterceptor; +import top.charles7c.continew.starter.security.crypto.core.MyBatisEncryptInterceptor; + +/** + * 加/解密自动配置 + * + * @author Charles7c + * @since 1.4.0 + */ +@AutoConfiguration +@EnableConfigurationProperties(CryptoProperties.class) +@ConditionalOnProperty(prefix = PropertiesConstants.CRYPTO, name = PropertiesConstants.ENABLED, havingValue = "true", matchIfMissing = true) +public class CryptoAutoConfiguration { + + private static final Logger log = LoggerFactory.getLogger(CryptoAutoConfiguration.class); + private final CryptoProperties properties; + + public CryptoAutoConfiguration(CryptoProperties properties) { + this.properties = properties; + } + + /** + * MyBatis 加密拦截器配置 + */ + @Bean + @ConditionalOnMissingBean(MyBatisEncryptInterceptor.class) + public MyBatisEncryptInterceptor myBatisEncryptInterceptor() { + return new MyBatisEncryptInterceptor(properties); + } + + /** + * MyBatis 解密拦截器配置 + */ + @Bean + @ConditionalOnMissingBean(MyBatisDecryptInterceptor.class) + public MyBatisDecryptInterceptor myBatisDecryptInterceptor() { + return new MyBatisDecryptInterceptor(properties); + } + + @PostConstruct + public void postConstruct() { + log.debug("[ContiNew Starter] - Auto Configuration 'Security-Crypto' completed initialization."); + } +} diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/autoconfigure/CryptoProperties.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/autoconfigure/CryptoProperties.java new file mode 100644 index 00000000..a4df2104 --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/autoconfigure/CryptoProperties.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 top.charles7c.continew.starter.security.crypto.autoconfigure; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import top.charles7c.continew.starter.core.constant.PropertiesConstants; + +/** + * 加/解密配置属性 + * + * @author Charles7c + * @since 1.4.0 + */ +@ConfigurationProperties(PropertiesConstants.CRYPTO) +public class CryptoProperties { + + /** + * 是否启用加/解密配置 + */ + private boolean enabled = true; + + /** + * 对称加密算法密钥 + */ + private String password; + + /** + * 非对称加密算法公钥 + */ + private String publicKey; + + /** + * 非对称加密算法私钥 + */ + private String privateKey; + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + } +} \ No newline at end of file diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/core/AbstractMyBatisInterceptor.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/core/AbstractMyBatisInterceptor.java new file mode 100644 index 00000000..378f0ae5 --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/core/AbstractMyBatisInterceptor.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 top.charles7c.continew.starter.security.crypto.core; + +import cn.hutool.core.util.ReflectUtil; +import cn.hutool.extra.spring.SpringUtil; +import org.apache.ibatis.plugin.*; +import top.charles7c.continew.starter.security.crypto.annotation.FieldEncrypt; +import top.charles7c.continew.starter.security.crypto.encryptor.IEncryptor; +import top.charles7c.continew.starter.security.crypto.enums.Algorithm; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * 字段解密拦截器 + * + * @author Charles7c + * @since 1.4.0 + */ +public abstract class AbstractMyBatisInterceptor implements Interceptor { + + /** + * 获取所有字符串类型、需要加/解密的、有值字段 + * + * @param obj 对象 + * @return 字段列表 + */ + public List getEncryptFields(Object obj) { + if (null == obj) { + return Collections.emptyList(); + } + return Arrays.stream(ReflectUtil.getFields(obj.getClass())) + .filter(field -> String.class.equals(field.getType())) + .filter(field -> null != field.getAnnotation(FieldEncrypt.class)) + .filter(field -> null != ReflectUtil.getFieldValue(obj, field)) + .toList(); + } + + /** + * 获取字段加/解密处理器 + * + * @param field 字段 + * @return 加/解密处理器 + */ + public IEncryptor getEncryptor(Field field) { + FieldEncrypt fieldEncrypt = field.getAnnotation(FieldEncrypt.class); + Class encryptorClass = fieldEncrypt.encryptor(); + // 使用预定义加/解密处理器 + if (encryptorClass == IEncryptor.class) { + Algorithm algorithm = fieldEncrypt.value(); + return ReflectUtil.newInstance(algorithm.getEncryptor()); + } + // 使用自定义加/解密处理器 + return SpringUtil.getBean(encryptorClass); + } +} \ No newline at end of file diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/core/MyBatisDecryptInterceptor.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/core/MyBatisDecryptInterceptor.java new file mode 100644 index 00000000..9290023f --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/core/MyBatisDecryptInterceptor.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 top.charles7c.continew.starter.security.crypto.core; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.ReflectUtil; +import org.apache.ibatis.executor.resultset.ResultSetHandler; +import org.apache.ibatis.plugin.*; +import org.apache.ibatis.type.SimpleTypeRegistry; +import top.charles7c.continew.starter.security.crypto.annotation.FieldEncrypt; +import top.charles7c.continew.starter.security.crypto.autoconfigure.CryptoProperties; +import top.charles7c.continew.starter.security.crypto.encryptor.IEncryptor; + +import java.lang.reflect.Field; +import java.sql.Statement; +import java.util.List; + +/** + * 字段解密拦截器 + * + * @author Charles7c + * @since 1.4.0 + */ +@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})}) +public class MyBatisDecryptInterceptor extends AbstractMyBatisInterceptor { + + private CryptoProperties properties; + + public MyBatisDecryptInterceptor(CryptoProperties properties) { + this.properties = properties; + } + + public MyBatisDecryptInterceptor() { + } + + @Override + public Object intercept(Invocation invocation) throws Throwable { + Object obj = invocation.proceed(); + if (null == obj || !(invocation.getTarget() instanceof ResultSetHandler)) { + return obj; + } + List resultList = (List)obj; + for (Object result : resultList) { + // String、Integer、Long 等简单类型对象无需处理 + if (SimpleTypeRegistry.isSimpleType(result.getClass())) { + continue; + } + // 获取所有字符串类型、需要解密的、有值字段 + List fieldList = super.getEncryptFields(result); + // 解密处理 + for (Field field : fieldList) { + IEncryptor encryptor = super.getEncryptor(field); + Object fieldValue = ReflectUtil.getFieldValue(result, field); + // 优先获取自定义对称加密算法密钥,获取不到时再获取全局配置 + String password = ObjectUtil.defaultIfBlank(field.getAnnotation(FieldEncrypt.class) + .password(), properties.getPassword()); + String ciphertext = encryptor.decrypt(fieldValue.toString(), password, properties.getPrivateKey()); + ReflectUtil.setFieldValue(result, field, ciphertext); + } + } + return resultList; + } +} \ No newline at end of file diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/core/MyBatisEncryptInterceptor.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/core/MyBatisEncryptInterceptor.java new file mode 100644 index 00000000..b3cb7c1b --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/core/MyBatisEncryptInterceptor.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 top.charles7c.continew.starter.security.crypto.core; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.ReflectUtil; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlCommandType; +import org.apache.ibatis.plugin.*; +import top.charles7c.continew.starter.security.crypto.annotation.FieldEncrypt; +import top.charles7c.continew.starter.security.crypto.autoconfigure.CryptoProperties; +import top.charles7c.continew.starter.security.crypto.encryptor.IEncryptor; + +import java.lang.reflect.Field; +import java.util.*; + +/** + * 字段加密拦截器 + * + * @author Charles7c + * @since 1.4.0 + */ +@Intercepts({@Signature(method = "update", type = Executor.class, args = {MappedStatement.class, Object.class}),}) +public class MyBatisEncryptInterceptor extends AbstractMyBatisInterceptor { + + private CryptoProperties properties; + + public MyBatisEncryptInterceptor(CryptoProperties properties) { + this.properties = properties; + } + + public MyBatisEncryptInterceptor() { + } + + @Override + public Object intercept(Invocation invocation) throws Throwable { + Object[] args = invocation.getArgs(); + MappedStatement mappedStatement = (MappedStatement)args[0]; + SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType(); + if (!(SqlCommandType.UPDATE == sqlCommandType || SqlCommandType.INSERT == sqlCommandType)) { + return invocation.proceed(); + } + Object obj = args[1]; + // 兼容 MyBatis Plus 封装的 update 相关方法,updateById、update + if (obj instanceof Map map) { + Object entity = map.get(Constants.ENTITY); + this.doEncrypt(this.getEncryptFields(entity), entity); + } else { + this.doEncrypt(this.getEncryptFields(obj), obj); + } + return invocation.proceed(); + } + + /** + * 处理加密 + * + * @param fieldList 加密字段列表 + * @param entity 实体 + * @throws Exception / + */ + private void doEncrypt(List fieldList, Object entity) throws Exception { + for (Field field : fieldList) { + IEncryptor encryptor = super.getEncryptor(field); + Object fieldValue = ReflectUtil.getFieldValue(entity, field); + // 优先获取自定义对称加密算法密钥,获取不到时再获取全局配置 + String password = ObjectUtil.defaultIfBlank(field.getAnnotation(FieldEncrypt.class).password(), properties + .getPassword()); + String ciphertext = encryptor.encrypt(fieldValue.toString(), password, properties.getPublicKey()); + ReflectUtil.setFieldValue(entity, field, ciphertext); + } + } +} diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/encryptor/AesEncryptor.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/encryptor/AesEncryptor.java new file mode 100644 index 00000000..f9a453ad --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/encryptor/AesEncryptor.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 top.charles7c.continew.starter.security.crypto.encryptor; + +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.symmetric.AES; + +import java.nio.charset.StandardCharsets; + +/** + * AES(Advanced Encryption Standard) 加/解密处理器 + *

+ * 美国国家标准与技术研究院(NIST)采纳的对称加密算法标准,提供128位、192位和256位三种密钥长度,以高效和安全性著称。 + *

+ * + * @author Charles7c + * @since 1.4.0 + */ +public class AesEncryptor implements IEncryptor { + + @Override + public String encrypt(String plaintext, String password, String publicKey) throws Exception { + AES aes = SecureUtil.aes(password.getBytes(StandardCharsets.UTF_8)); + return aes.encryptHex(plaintext); + } + + @Override + public String decrypt(String ciphertext, String password, String privateKey) throws Exception { + AES aes = SecureUtil.aes(password.getBytes(StandardCharsets.UTF_8)); + return aes.decryptStr(ciphertext); + } +} diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/encryptor/Base64Encryptor.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/encryptor/Base64Encryptor.java new file mode 100644 index 00000000..488aac13 --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/encryptor/Base64Encryptor.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 top.charles7c.continew.starter.security.crypto.encryptor; + +import cn.hutool.core.codec.Base64; + +/** + * Base64 加/解密处理器 + *

+ * 一种用于编码二进制数据到文本格式的算法,常用于邮件附件、网页传输等场合,但它不是一种加密算法,只提供数据的编码和解码,不保证数据的安全性。 + *

+ * + * @author Charles7c + * @since 1.4.0 + */ +public class Base64Encryptor implements IEncryptor { + + @Override + public String encrypt(String plaintext, String password, String publicKey) throws Exception { + return Base64.encode(plaintext); + } + + @Override + public String decrypt(String ciphertext, String password, String privateKey) throws Exception { + return Base64.decodeStr(ciphertext); + } +} diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/encryptor/IEncryptor.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/encryptor/IEncryptor.java new file mode 100644 index 00000000..61672ddc --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/encryptor/IEncryptor.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 top.charles7c.continew.starter.security.crypto.encryptor; + +/** + * 加/解密接口 + * + * @author Charles7c + * @since 1.4.0 + */ +public interface IEncryptor { + + /** + * 加密 + * + * @param plaintext 明文 + * @param password 对称加密算法密钥 + * @param publicKey 非对称加密算法公钥 + * @return 加密后的文本 + * @throws Exception / + */ + String encrypt(String plaintext, String password, String publicKey) throws Exception; + + /** + * 解密 + * + * @param ciphertext 密文 + * @param password 对称加密算法密钥 + * @param privateKey 非对称加密算法私钥 + * @return 解密后的文本 + * @throws Exception / + */ + String decrypt(String ciphertext, String password, String privateKey) throws Exception; +} diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/encryptor/RsaEncryptor.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/encryptor/RsaEncryptor.java new file mode 100644 index 00000000..e49c4214 --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/encryptor/RsaEncryptor.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 top.charles7c.continew.starter.security.crypto.encryptor; + +import cn.hutool.core.codec.Base64; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.asymmetric.KeyType; + +/** + * RSA 加/解密处理器 + *

+ * 非对称加密算法,由罗纳德·李维斯特(Ron Rivest)、阿迪·沙米尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)于1977年提出,安全性基于大数因子分解问题的困难性。 + *

+ * + * @author Charles7c + * @since 1.4.0 + */ +public class RsaEncryptor implements IEncryptor { + + @Override + public String encrypt(String plaintext, String password, String publicKey) throws Exception { + return Base64.encode(SecureUtil.rsa(null, publicKey).encrypt(plaintext, KeyType.PublicKey)); + } + + @Override + public String decrypt(String ciphertext, String password, String privateKey) throws Exception { + return new String(SecureUtil.rsa(privateKey, null).decrypt(Base64.decode(ciphertext), KeyType.PrivateKey)); + } +} diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/enums/Algorithm.java b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/enums/Algorithm.java new file mode 100644 index 00000000..6eaa040e --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/src/main/java/top/charles7c/continew/starter/security/crypto/enums/Algorithm.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * 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 top.charles7c.continew.starter.security.crypto.enums; + +import top.charles7c.continew.starter.security.crypto.encryptor.AesEncryptor; +import top.charles7c.continew.starter.security.crypto.encryptor.Base64Encryptor; +import top.charles7c.continew.starter.security.crypto.encryptor.IEncryptor; +import top.charles7c.continew.starter.security.crypto.encryptor.RsaEncryptor; + +/** + * 加密/解密算法枚举 + * + * @author Charles7c + * @since 1.4.0 + */ +public enum Algorithm { + + /** + * AES + */ + AES(AesEncryptor.class), + + /** + * RSA + */ + RSA(RsaEncryptor.class), + + /** + * Base64 + */ + BASE64(Base64Encryptor.class),; + + /** + * 加密/解密处理器 + */ + private final Class encryptor; + + Algorithm(Class encryptor) { + this.encryptor = encryptor; + } + + public Class getEncryptor() { + return encryptor; + } +} diff --git a/continew-starter-security/continew-starter-security-crypto/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/continew-starter-security/continew-starter-security-crypto/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..c4a825ee --- /dev/null +++ b/continew-starter-security/continew-starter-security-crypto/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +top.charles7c.continew.starter.security.crypto.autoconfigure.CryptoAutoConfiguration \ No newline at end of file diff --git a/continew-starter-security/pom.xml b/continew-starter-security/pom.xml index 892a1bf9..666fad34 100644 --- a/continew-starter-security/pom.xml +++ b/continew-starter-security/pom.xml @@ -16,6 +16,7 @@ continew-starter-security-password continew-starter-security-mask + continew-starter-security-crypto