本文主要是介绍springboot实现配置文件关键信息加解密,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《springboot实现配置文件关键信息加解密》在项目配置文件中常常会配置如数据库连接信息,redis连接信息等,连接密码明文配置在配置文件中会很不安全,所以本文就来聊聊如何使用springboot...
前言
在项目配置文件中常常会配置如数据库连接信息、Redis连接信息,而连接密码明文配置在配置文件中会很不安全,所以就会将密码信息加密后放在配置文件中,在启动项目时自动解密转换成明文后进行连接,防止密码泄露。
方案
1、实现 EnvironmentPostProcessor 接口
2、引入 jasypt-spring-boot-starter 依赖
实践
1、第一种方案
EnvironmentPostProcessor
是 Spring Boot 提供的一个接口,用于在 Spring Boot 的 Environment
初始化完成后对其进行进一步的处理。它允许你在 Spring Boot 的配置加载阶段动态修改或增强 Environment
的内容,例如添加额外的配置源、修改属性值等。 ### 作用和用途
EnvironmentPostProcessor
的主要作用是在 Spring Boot 的启动过程中,对 Environment
对象进行扩展或修改。它通常用于以下场景:
- 动态添加配置源:例如,从远程配置中心(如 Spring Cloud Config Server、Consul 等)加载配置。
- 修改或覆盖配置属性:例如,根据环境变量或命令行参数动态调整某些配置值。
- 解析加密的配置属性:例如,解密配置文件中加密的敏感信息。
- 添加自定义的配置解析逻辑:例如,支持自定义的配置文件格式或解析规则。
使用方法
实现 EnvironmentPostProcessor
接口,并将自定义实现类注册到springboot中
import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import orgphp.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import Java.util.HashMap; import java.util.Map; /** * 自定义EnvironmentPostProcessor,在spring启动前将遍历配置文件中是否有加密的值,将加密的值按自定义解密工具进行解密 */ @Order(Ordered.HIGHEST_PRECEDENCE) public class DecryptEnvironmentPostProcessor implements EnvironmentPostProcessor { @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { environment.getPropertySources().forEach(propertySource -> { if (propertySource instanceof MapPropertySource) { MapPropertySource mapSource = (MapPropertySource) propertySource; Map<String, Object> originalSource = mapSource.getSource(); www.chinasem.cn // 创建新的可修改 Map 副本 Map<String, Object> decryptedSource = new HashMap<>(originalSource); // 遍历并解密值 decryptedSource.replaceAll((key, value) -> { if (value instanceof String) { String strValue = (String) value; if (strValue.startsWith("ENC(") && strValue.endsWith(")")) { String encryptedContent = strValue.substring(4, strValue.length() - 1); return AESEncryptionUtils.decrypt(encryptedContent); } } return value; }); // 用解密后的 Map 替换原 PropertySource environment.getPropertySources().replace( mapSource.getName(), new MapPropertySource(mapSource.getName(), decryptedSource) ); } }); } }
注册 EnvironmentPostProcessor
实现类
在 META-INF/spring.factories
文件中注册你的 EnvironmentPostProcessor
。
org.springframework.boot.env.EnvironmentPostProcessor=\ com.example.DecryptEnvironmentPostProcessor
自定义加解密工具类
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.security.SecureRandom; public class AESEncryptionUtils { private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; // 使用 CBC 模式 + PKCS5 填充 private static final String SECRET_KEY = "oJ51lypwUNzBIFXO"; // 密钥环境变量名称 /** * 加密明文 * @param plaintext 待加密的明文 * @return 格式为 "Base64(IV):Base64(密文)" 的字符串 */ public static String encrypt(String plaintext) { try { // 生成随机 IV byte[] ivbytes = new byte[16]; SecureRandom random = new SecureRandom(); random.nextBytes(ivBytes); IvParameterSpec iv = new IvParameterSpec(ivBytes); // 初始化加密器 SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), "AES"); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv); // 执行加密 byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); // 组合 IV 和密文,用 Base64 编码 String iVBAse64 = Base64.getEncoder().encodeToString(ivBytes); String encryptedBase64 = Base64.getEncoder().encodeToString(encryptedBytes); return ivBase64 + ":" + encryptedBase64; } catch (Exception epython) { throw new RuntimeException("加密失败", e); } } /** * 解密密文 * @param encryptedText 格式为 "Base64(IV):Base64(密文)" 的字符串 * @return 解密后的明文 */ public static String decrypthttp://www.chinasem.cn(String encryptedText) { try { // 拆分 IV 和密文 String[] parts = encryptedText.split(":"); if (parts.length != 2) { throw new IllegalArgumentException("无效的加密格式"); } byte[] ivBytes = Base64.getDecoder().decode(parts[0]); byte[] encryptedBytes = Base64.getDecoder().decode(parts[1]); // 初始化解密器 IvParameterSpec iv = new IvParameterSpec(ivBytes); SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), "AES"); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, keySpec, iChina编程v); // 执行解密 byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes, StandardCharsets.UTF_8); } catch (Exception e) { throw new RuntimeException("解密失败", e); } } }
2、第二种方案
引入依赖
在项目的 pom.XML
文件中添加以下依赖:
<dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.4</version> </dependency>
配置 jasypt 信息
jasypt: encryptor: password: encryption-key algorithm: PBEWithMD5AndDES iv-generator-classname: org.jasypt.iv.NoIvGenerator
密码加密
从 Jasypt 官方网站 或 Maven 中央仓库下载 jasypt-1.9.3.jar
。
使用 Jasypt 的命令行工具对配置信息进行加密。例如,加密数据库密码:
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="123456" password=encryption-key algorithm=PBEWithMD5AndDES
上述命令会输出一个加密后的字符串,例如:
在配置文件中配置加密后的字符串:
spring: datasource: password: ENC(pxaWXichlG6mranljAUiZQ==)
在应用启动时,jasypt
会使用密钥解密 ENC()
中的内容,并将其值注入到对应的配置属性中。
jasypt 加解密工具类
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor; /** * jasypt 解密工具类 */ public class EncryptionUtil { public static String encrypt(String input, String password) { StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); encryptor.setPassword(password); return encryptor.encrypt(input); } public static String decrypt(String encryptedValue, String password) { StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); encryptor.setPassword(password); return encryptor.decrypt(encryptedValue); } }
补充
jasypt
密钥配置到配置文件中其实也不太安全,更安全的做法是将密钥配置到环境变量中或设置在启动命令中
export JASYPT_ENCRYPTOR_PASSWORD=your-encryption-key
java -jar your-application.jar --jasypt.encryptor.password=your-encryption-key
到此这篇关于springboot实现配置文件关键信息加解密的文章就介绍到这了,更多相关springboot配置文件信息加解密内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!
这篇关于springboot实现配置文件关键信息加解密的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!