在 Spring Boot 中为 Redis 密码实现自定义加解密,核心思路是:配置文件中存储加密后的密码 → 启动时通过自定义 Bean 解密 → 将解密后的明文设置到 RedisConnectionFactory。以下是完整实践方案,包含加密工具、配置、Bean 定义及安全注意事项。
![图片[1]_Redis密码在springboot中自定义加解密实践_知途无界](https://zhituwujie.com/wp-content/uploads/2026/01/d2b5ca33bd20260112110517.png)
一、整体流程
- 加密原始密码:使用自定义加密算法(如 AES、Base64 增强版等)对 Redis 原始密码加密,存储到
application.yml。 - 自定义解密逻辑:在 Spring Boot 启动时,通过
@Configuration类读取加密密码,调用解密工具还原明文。 - 注入 Redis 连接池:将解密后的明文设置到
RedisStandaloneConfiguration或LettuceConnectionFactory,完成 Redis 连接。
二、步骤 1:定义加密/解密工具类
选择一个安全的加密算法(避免使用 Base64 等“伪加密”),这里以 AES 对称加密为例(需妥善保管密钥)。
1.1 AES 加密工具类(需引入 commons-codec 依赖)
<!-- pom.xml 依赖 -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.16.1</version>
</dependency>
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
/**
* AES 加密工具类(密钥需 16/24/32 字节,对应 AES-128/AES-192/AES-256)
*/
public class AESUtils {
// 密钥(生产环境需存储在安全位置,如环境变量、配置中心,避免硬编码)
private static final String SECRET_KEY = "MySecretKey123456"; // 16字节(AES-128)
private static final String ALGORITHM = "AES/ECB/PKCS5Padding"; // 算法模式
/**
* AES 加密
*/
public static String encrypt(String plainText) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64String(encryptedBytes); // 转为 Base64 字符串存储
}
/**
* AES 解密
*/
public static String decrypt(String encryptedText) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] decodedBytes = Base64.decodeBase64(encryptedText);
byte[] decryptedBytes = cipher.doFinal(decodedBytes);
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
}
1.2 生成加密后的密码(测试用)
public class TestEncrypt {
public static void main(String[] args) throws Exception {
String rawPassword = "my_redis_password_123"; // 原始密码
String encryptedPassword = AESUtils.encrypt(rawPassword);
System.out.println("加密后的密码:" + encryptedPassword);
// 输出示例:加密后的密码:U2FsdGVkX1+abc123...(实际为 Base64 字符串)
}
}
将输出的加密字符串(如 U2FsdGVkX1+abc123...)存入配置文件。
三、步骤 2:Spring Boot 配置与解密 Bean
2.1 配置文件(application.yml)
存储加密后的密码,避免明文暴露:
spring:
redis:
host: 192.168.1.100
port: 6379
# 存储加密后的密码(替换为实际加密结果)
password: U2FsdGVkX1+abc123... # 加密后的密码
timeout: 2000ms
lettuce:
pool:
max-active: 8
max-wait: -1ms
max-idle: 8
min-idle: 0
2.2 自定义 Redis 配置类(核心)
通过 @Configuration 定义 RedisConnectionFactory,在初始化时解密密码并设置。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import java.time.Duration;
@Configuration
public class RedisConfig {
@Value("${spring.redis.host:localhost}")
private String host;
@Value("${spring.redis.port:6379}")
private int port;
@Value("${spring.redis.password:}") // 注入加密后的密码
private String encryptedPassword;
@Value("${spring.redis.timeout:2000ms}")
private Duration timeout;
@Value("${spring.redis.lettuce.pool.max-active:8}")
private int maxActive;
@Value("${spring.redis.lettuce.pool.max-idle:8}")
private int maxIdle;
@Value("${spring.redis.lettuce.pool.min-idle:0}")
private int minIdle;
@Value("${spring.redis.lettuce.pool.max-wait:-1ms}")
private Duration maxWait;
/**
* 解密 Redis 密码并创建连接工厂
*/
@Bean
public LettuceConnectionFactory redisConnectionFactory() throws Exception {
// 1. 解密密码(调用自定义解密工具)
String rawPassword = AESUtils.decrypt(encryptedPassword); // 若解密失败会抛异常
// 2. 配置 Redis 服务器信息
RedisStandaloneConfiguration serverConfig = new RedisStandaloneConfiguration();
serverConfig.setHostName(host);
serverConfig.setPort(port);
serverConfig.setPassword(RedisPassword.of(rawPassword)); // 设置解密后的明文密码
// 3. 配置连接池(Lettuce)
LettucePoolingClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
.commandTimeout(timeout)
.poolConfig(LettucePoolingClientConfiguration.builder()
.maxTotal(maxActive)
.maxIdle(maxIdle)
.minIdle(minIdle)
.maxWait(maxWait)
.build())
.build();
// 4. 创建并返回连接工厂
return new LettuceConnectionFactory(serverConfig, clientConfig);
}
}
2.3 验证 RedisTemplate 可用性
确保 RedisTemplate 能正常使用(Spring Boot 会自动注入 redisConnectionFactory):
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class TestController {
@Resource
private RedisTemplate<String, Object> redisTemplate;
public void testRedis() {
redisTemplate.opsForValue().set("test:key", "hello_redis");
String value = (String) redisTemplate.opsForValue().get("test:key");
System.out.println("Redis 读取结果:" + value); // 输出 hello_redis
}
}
四、关键注意事项
4.1 密钥安全管理
- 禁止硬编码密钥:示例中密钥写在代码里仅为演示,生产环境需将密钥存储在 环境变量、配置中心(如 Nacos/Apollo) 或 密钥管理服务(如 HashiCorp Vault)。
示例(从环境变量读取密钥):private static final String SECRET_KEY = System.getenv("REDIS_AES_SECRET_KEY"); // 环境变量注入 - 限制密钥访问权限:确保密钥仅应用进程可读,避免泄露。
4.2 加密算法选择
- 避免弱加密:Base64 仅为编码(可逆且无安全性),不可用于密码保护;推荐使用 AES-256-GCM(带认证)或 RSA(非对称加密,适合分布式场景)。
- 算法参数安全:AES 的 ECB 模式不安全(相同明文生成相同密文),示例中使用
AES/ECB/PKCS5Padding仅为简化,生产环境建议用AES/GCM/NoPadding(需处理 IV 向量)。
4.3 异常处理
- 解密失败处理:若加密密码格式错误或密钥不匹配,
AESUtils.decrypt()会抛异常,需在redisConnectionFactory()中捕获并处理(如启动失败并提示配置错误)。try { String rawPassword = AESUtils.decrypt(encryptedPassword); } catch (Exception e) { throw new IllegalStateException("Redis 密码解密失败,请检查配置", e); } - 配置文件校验:启动时校验
spring.redis.password是否为空或无效加密串,提前暴露问题。
4.4 其他方案对比
- Spring Cloud Config + 加密:若使用 Spring Cloud Config,可结合其内置的
{cipher}xxx加密功能(基于 JCE),但需配置密钥服务器。 - 第三方库:如
jasypt-spring-boot,通过@Encrypted注解自动解密配置(需引入依赖并配置密钥),适合快速集成。
总结
通过 自定义加解密工具 + Spring Boot 配置类,可实现 Redis 密码的安全存储与动态解密。核心是隔离加密逻辑与业务代码,并通过安全的密钥管理保障解密过程的安全性。生产环境中需重点关注密钥管理和加密算法的强度,避免因配置不当导致密码泄露。
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END

























暂无评论内容