jasypt明文加密

404 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看详情

该文章只包含数据库明文地址/密码/用户名加密,不包含用户信息加密内容.

需求:当前需求为在SpringCloud项目中隐藏Nacos配置文件中的数据库连接用户名密码等明文信息;要求使用密钥加密明文密码后将密钥使用明文盐值再次加密,明文盐值可见,项目启动自动获取盐值解密密钥,通过密钥解密密码进行数据库连接;

使用技术为Jasypt,版本为3.0.3,该版本可以使用简便方式进行数据库等信息加密解密,使用简单;

使用依赖:
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

解密通过实现StringEncryptor接口重写解密方法达到自定义解密方法解密需求;

自定义解密配置
@Configuration
public class JasyPtEncryptionConfig {
    @Bean("jasyptStringEncryptor")
    public StringEncryptor stringEncryptor() {
        DESEncrypt desEncrypt = new DESEncrypt();
        return desEncrypt;
    }
}
自定义加密、解密方法
@Slf4j
public class DESEncrypt implements StringEncryptor {

    @Value("${jasypt.encryptor.passSecret}")
    private String passSecret;

    @Override
    public String encrypt(String s) {
        return null;
    }

    /**
     * 解密
     *
     * @param pass 加密的密码/用户名等信息
     * @return
     */
    @Override
    public String decrypt(String pass) {
        //启动类获取
        String secretB = System.getProperty("jasypt.encryptor.secretB");
        if (StringUtils.isBlank(pass) && StringUtils.isBlank(secretB)) {
            log.error("当前获取密钥错误");
            return null;
        }
        //先用获取的b密钥解密a
        String decryptSecretA = decryptPass(passSecret, secretB);
        //再用a解密数据库密码等
        String outPass = decryptPass(pass, decryptSecretA);
        System.out.println(outPass);
        return outPass;
    }

    public String decryptPass(String encryptedText, String factor) {
        // 1. 创建加解密工具实例
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        // 2. 加解密配置
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(factor);
        config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        // 为减少配置文件的书写,以下都是 Jasyp 3.x 版本,配置文件默认配置
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);
        // 3. 解密
        return encryptor.decrypt(encryptedText);

    }

    public static String decryptWithSHA512(String plainText, String factor) {
        // 1. 创建加解密工具实例
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        // 2. 加解密配置
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(factor);
        config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        // 为减少配置文件的书写,以下都是 Jasyp 3.x 版本,配置文件默认配置
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);
        // 3. 解密
        return encryptor.decrypt(plainText);
    }


    public static String encryptWithSHA512(String plainText, String factor) {
        // 1. 创建加解密工具实例
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        // 2. 加解密配置
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(factor);
        config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        // 为减少配置文件的书写,以下都是 Jasyp 3.x 版本,配置文件默认配置
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);
        // 3. 加密
        return encryptor.encrypt(plainText);
    }

    public static void main(String[] args) {
        UUID randomUUID = UUID.randomUUID();
        String uuid = randomUUID.toString().replace("-", "");
        String s = encryptWithSHA512(uuid, "secretB");
        System.out.println("需要设定的密钥:" + s);
        String s1 = encryptWithSHA512("${MYSQL-PWD:***}", uuid);
        System.out.println("密码:" + s1);
        String s2 = encryptWithSHA512(
                "jdbc:mysql://${MYSQL-HOST:***}:${MYSQL-PORT:3306}/${MYSQL-DB:nacos}?characterEncoding=utf8&connectTimeout=10000&socketTimeout=30000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true",
                uuid);
        System.out.println("地址:" + s2);
        String s3 = encryptWithSHA512("${MYSQL-USER:***}", uuid);
        System.out.println("用户名:" + s3);
        String s4 = decryptWithSHA512(s1, uuid);
        System.out.println("解密密码:" + s4);
    }
}

其中加密过的密钥保存再配置文件中

jasypt:
  encryptor:
    algorithm: PBEWITHHMACSHA512ANDAES_256
    passSecret: 加密过的密钥

明文盐值放置在启动命令中

-Djasypt.encryptor.secretB=secretB

![加密.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/435c3aeca5e44715918ac6d4116fb83c~tplv-k3u1fbpfcp-watermark.image?)

配置文件中密码、用户名使用ENC()包裹即可实现;

db:
  num: 1
  password:
    '0': ENC(3fg2aEiqqQyDU3ZSd8GMJa0p2U+O4rDd+vdmRMx0b2ZEoNnPTaYjY2vzo56kzWdUkzImCIqCXDrfTn1pYNCW4g==)
  url:
    '0': ENC(pGIlhA1s221wtfRPgI6sNDWhmBUS1VjeCyg2UmNbT3nd06Pmqj5o5zi2R5VS9D5X1m6tfOkqch9bbvzKm84wkxctt763YkqAEZkcpDYkY/ZYN6ZbLE2qGlyC3TUXsCXd0o/47Wr2JxRRHcS/aYOm2MRlBkGyB6DLibDU3uZs+l84NDSm3K2SNdUsQdMNrVwSt0jCYKilqVFZDLQDJkwpgZCfcMxcF/ySylD4w3qcsSGs702Nrtt/n8R9EeN7wPQLovZbhNT9yZGCFmUl005XnO24ggGjTQ31EQaYFq30yp3AL6dpl+urZDck6Y1xjpNPK4YGxXJ2/NLOjCvr2IpvArKPjxPNl7Mc8yEA+BxA63U=)
  user:
    '0': ENC(g8KrO5Wm7+ojgfHaI8lYfudzbpCgN4a)

注意问题:使用3.0.3版本会出现 # Failed to bind properties under ‘xxx.xxx.xxx‘ to java.lang.String 首先检查代码逻辑,代码逻辑无问题可以尝试替换文件; 文件地址:

1、打开以下网址,下载JCE压缩包:
JCE Unlimited Strength Jurisdiction Policy Files for JDK/JRE 8 Download

2、把解压出来的local_policy.jar、US_export_policy.jar替换掉jdk1.8.0_144/jre/lib/security下的2个jar包(先备份后替换)