Spring中如何实现可双向还原的String字符串编码与解码?
可行解决方案
方案1:使用Spring Security官方未弃用的对称加密实现
Spring Security 弃用org.springframework.security.crypto.encrypt.Encryptors.queryableText()的核心原因是该方法默认加密算法强度较低,官方推荐使用安全性更高的Encryptors.stronger()实现可逆对称加密,完全可以满足你加密存储、读取解密的需求:
- 依赖要求:确保项目引入
spring-security-crypto依赖 - 用法示例:
// 构造加密器,第一个参数为自定义的加密密钥,第二个参数为16位十六进制格式的盐值 TextEncryptor encryptor = Encryptors.stronger("你的自定义加密密钥", "16位十六进制盐值"); // 加密得到可存入数据库的密文 String encryptedText = encryptor.encrypt("需要存储的原始字符串"); // 从数据库读取密文后解密还原 String originalText = encryptor.decrypt(encryptedText);
注意:加密密钥和盐需要妥善存储,不要硬编码在业务代码中,建议存放到配置中心或专门的机密管理服务中
方案2:自主实现AES-GCM加密(不依赖Spring生态)
如果不想依赖Spring Security的加密模块,可以自主实现工业界通用的AES-GCM对称加密方案,该算法安全性高、自带防篡改校验:
- 固定选择
AES/GCM/NoPadding算法,可使用128/256位密钥(256位密钥需要提前配置JCE无限制权限策略文件 - 加密后得到的字节数组转成Base64字符串即可直接存入数据库字段
方案3:需支持密文等值查询的特殊适配
如果你的业务场景需要直接对加密字段做等值查询(比如按加密手机号匹配用户,不需要解密全表解密效率太低),可以额外加一个单独的哈希字段:对原始字符串加盐后做SHA-256哈希,将哈希值单独存储,查询时用同样的规则计算哈希值匹配即可,不需要解密每行数据。
注意事项
- 加密密钥禁止和密文存储在同一个数据库实例中,避免数据库拖库后密钥同时泄露导致所有数据被破解
- 加密后的字符串长度会比原始字符串长,需要提前给数据库字段预留足够的存储空间
- 禁止使用ECB模式的AES加密,该模式安全性极低
- 加密后的字节数组建议转成Base64或Hex编码后再存储,避免特殊字符导致数据库存储异常
内容的提问来源于stack exchange,提问作者The Celt
相关产品推荐
相关产品推荐

