使用jasypt对springboot项目 解密properties 配置文件加密
1.引入配置文件
<dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.4</version> </dependency>
方式一:
2.启动类添加注解(创建了配置文件可以不添加注解)
@EnableEncryptableProperties
@SpringBootApplication @EnableFeignClients(basePackages= {"com.mybatis.plus.web.client"}) @EnableHystrix @EnableScheduling @EnableEncryptableProperties public class PlusApplication { public static void main(String[] args) { SpringApplication.run(PlusApplication.class, args); } }
3.添加配置文件
package com.mybatis.plus.config.enc; import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyDetector; import org.springframework.stereotype.Component; @Component("encryptablePropertyDetector") public class Base64EncryptablePropertyDetector implements EncryptablePropertyDetector { private static final String PREFIX = "password:"; @Override public boolean isEncrypted(String property) { if (property == null) { return false; } return property.startsWith(PREFIX); } @Override public String unwrapEncryptedValue(String property) { return property.substring(PREFIX.length()); } }
package com.mybatis.plus.config.enc; import cn.hutool.core.lang.Console; import com.mybatis.plus.utils.DesUtil; import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Optional; @Component("encryptablePropertyResolver") public class Base64EncryptablePropertyResolver implements EncryptablePropertyResolver { @Autowired private Base64EncryptablePropertyDetector encryptablePropertyDetector; @Override public String resolvePropertyValue(String value) { return Optional.ofNullable(value) .filter(encryptablePropertyDetector::isEncrypted) .map(resolveValue -> { final String unwrapEncryptedValue = encryptablePropertyDetector.unwrapEncryptedValue(resolveValue); // return new String(Base64.getDecoder().decode(unwrapEncryptedValue), // StandardCharsets.UTF_8); return DesUtil.decrypt(unwrapEncryptedValue); }) .orElse(value); } public static void main(String[] args) { String encodeToString = Base64.getEncoder().encodeToString(new String("XM_zm2019").getBytes()); String s = new String(Base64.getDecoder().decode(encodeToString), StandardCharsets.UTF_8); Console.log(s); Console.log(encodeToString); } }
工具类:
package com.mybatis.plus.utils; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import java.security.SecureRandom; /** * DES常用解密加密工具类 */ public class DesUtil { public static void main(String[] args) throws Exception { long temp = System.currentTimeMillis(); //加密字符串 System.out.println("生成密钥消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒"); String message = "XM_zm2019"; System.out.println("原文:" + message); temp = System.currentTimeMillis(); String messageEn = encrypt(message); System.out.println("密文:" + messageEn); System.out.println("加密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒"); temp = System.currentTimeMillis(); String messageDe = decrypt(messageEn); System.out.println("解密:" + messageDe); System.out.println("解密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒"); } //默认的字符编码 private static final String DEFAULT_CHARSET = "utf-8"; //秘钥字符串 private static final String PASSWORD = "iJavanGe!@#+xMSzmigyx51JmN=="; //算法 private static final String ALGORITHM = "DES"; /** * 解密DES * @param datasource 需要加密的内容 * @return 解密后的明文 数据 */ public static String decrypt(String datasource){ try{ // 创建一个DESKeySpec对象,PASSWORD可任意指定 DESKeySpec desKey = new DESKeySpec(PASSWORD.getBytes()); // 创建一个密匙工厂 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); // 生成密钥 SecretKey secretkey = keyFactory.generateSecret(desKey); // 指定获取DES的Cipher对象 Cipher cipher = Cipher.getInstance(ALGORITHM); // 用密匙初始化Cipher对象 cipher.init(Cipher.DECRYPT_MODE, secretkey, new SecureRandom()); // 真正开始解密操作 return new String(cipher.doFinal(parseHexStr2Byte(datasource))); }catch(Throwable e){ e.printStackTrace(); } return null; } /** * 加密32位 * @param datasource 需要加密的内容 * @return 加密的内容 */ public static String encrypt(String datasource) { try{ DESKeySpec desKey = new DESKeySpec(PASSWORD.getBytes()); //创建一个密匙工厂,获取secretKey SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); SecretKey secretKey = keyFactory.generateSecret(desKey); //指定获取DES的Cipher对象 Cipher cipher = Cipher.getInstance(ALGORITHM); //用密匙初始化Cipher对象 cipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom()); //数据加密 return parseByte2HexStr(cipher.doFinal(datasource.getBytes(DEFAULT_CHARSET))); }catch(Throwable e){ e.printStackTrace(); } return null; } public static String parseByte2HexStr(byte[] buf) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < buf.length; ++i) { String hex = Integer.toHexString(buf[i] & 255); if (hex.length() == 1) { hex = '0' + hex; } sb.append(hex.toUpperCase()); } return sb.toString(); } private static byte[] parseHexStr2Byte(String hexStr) { if (hexStr.length() < 1) { return null; } else { byte[] result = new byte[hexStr.length() / 2]; for (int i = 0; i < hexStr.length() / 2; ++i) { int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16); int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16); result[i] = (byte) (high * 16 + low); } return result; } } }
使用:
# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/zongmu?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8&allowPublicKeyRetrieval=true username: root password: password:DB83AB023F35081C936DA71860F6EB63
方式二: 实现 StringEncryptor 接口 此方式不用启动类添加注解 但是只能使用ENC(XXX)的加密格式
1.添加配置文件
package com.mybatis.plus.config.enc; import com.mybatis.plus.utils.DesUtil; import org.apache.commons.lang3.StringUtils; import org.jasypt.encryption.StringEncryptor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Component("desencrypt") public class NrStringEncryptor implements StringEncryptor { private static Logger logger = LoggerFactory.getLogger(NrStringEncryptor.class); @Override public String encrypt(String message) { if (StringUtils.isNotBlank(message)){ try { // logger.info("加密前密码:"+message); message = DesUtil.encrypt(message); logger.info("加密后密码:"+message); logger.info("配置信息加密成功!"); } catch (Exception e) { logger.error("服务运行中:配置秘钥信息加密失败!"); } } return message; } @Override public String decrypt(String encryptedMessage) { if (StringUtils.isNotBlank(encryptedMessage)){ try { logger.info("解密前密码:"+encryptedMessage); encryptedMessage = DesUtil.decrypt(encryptedMessage); // logger.info("解密后密码:"+encryptedMessage); logger.info("配置信息解密成功!"); } catch (Exception e) { logger.error("服务启动中:配置秘钥信息解密失败,请检查配置是否正确!"); } } return encryptedMessage; } }
工具类同方式一
2.yml中增加配置
jasypt:
encryptor:
bean: desencrypt
3.使用示例
# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/zongmu?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8&allowPublicKeyRetrieval=true username: root password: ENC(DB83AB023F35081C936DA71860F6EB63)
⎛⎝官萧何⎠⎞一只快乐的爪哇程序猿;邮箱:1570608034@qq.com