使用 jasypt 为配置文件加密

617 阅读2分钟

需求

对于配置文件的敏感信息,例如数据库账号密码,一般我们会通过配置中心进行隔离,或者对配置文件解析器进行扩展,使其从环境变量中读取账号密码,今天我们用的jasypt也是通过第二种方式进行敏感数据加解密的。

使用

maven依赖

<dependency>
   <groupId>com.github.ulisesbocchio</groupId>
   <artifactId>jasypt-spring-boot-starter</artifactId>
   <version>3.0.4</version>
</dependency>

jar的引用方式有两种:

  • 引入jasypt-spring-boot-starter的话,项目中配置了@SpringBootApplication 或者 @EnableAutoConfiguration 就可以直接使用了
  • 引入了jasypt-spring-boot的话,项目需要配置@EnableEncryptableProperties才可以使用

使用方式一:使用默认算法配置加解密

# 配置解密密码
# 算法默认为:PBEWITHHMACSHA512ANDAES_256
jasypt:
  encryptor:
    password: turing
    //根据密码生成密文
    @Test
    public void testEnvironmentProperties() {
        //对应配置文件中对应的根密码
        System.setProperty("jasypt.encryptor.password", "turing");
        StandardEnvironment environment = new StandardEnvironment();
        StringEncryptor stringEncryptor = new DefaultLazyEncryptor(environment);

        //加密方法
        String username = stringEncryptor.encrypt("root");
        System.out.println(username);
        String password = stringEncryptor.encrypt("root");
        System.out.println(password);
        
        //解密方法
        System.out.println("username:" + stringEncryptor.decrypt(username));
        System.out.println("password:" + stringEncryptor.decrypt(password));
    }
# 将配置文件中的明文替换为生成的密文
# 注意,密文必须用ENC包起来
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/shares?autoReconnect=true&serverTimeZone=GMT&useSSL=false&rewriteBatchedStatements=true&useUnicode=true&characterEncoding=utf8
    username: ENC(Pta+24ztk+/o8HJs0pCjjQ==)
    password: ENC(0rL9fNGHs5Sbzp+L5r+yjA==)

使用方式二:使用自定义算法配置加密解密

# 配置解密密码
jasypt:
  encryptor:
    # 配置加密算法
    algorithm: PBEWithMD5AndDES
    # PBEWithMD5AndDES 算法在jdk8下使用会出异常,需要配置如下generator
    iv-generator-classname: org.jasypt.iv.NoIvGenerator
    password: turing
//根据密码生成密文
public class JasyptUtil {
    public static void main(String[] args) {
        String username = JasyptUtil.encryptPwd("turing", "root");
        System.out.println(username);
        String password = JasyptUtil.encryptPwd("turing", "root");
        System.out.println(password);

        System.out.println(JasyptUtil.decyptPwd("turing", username));
        System.out.println(JasyptUtil.decyptPwd("turing", password));
    }

    /**
     * Jasypt生成加密结果
     *
     * @param password 配置文件中设定的加密密码 jasypt.encryptor.password
     * @param value    待加密值
     * @return
     */
    public static String encryptPwd(String password, String value) {
        PooledPBEStringEncryptor encryptOr = new PooledPBEStringEncryptor();
        encryptOr.setConfig(cryptOr(password));
        String result = encryptOr.encrypt(value);
        return result;
    }

    /**
     * 解密
     *
     * @param password 配置文件中设定的加密密码 jasypt.encryptor.password
     * @param value    待解密密文
     * @return
     */
    public static String decyptPwd(String password, String value) {
        PooledPBEStringEncryptor encryptOr = new PooledPBEStringEncryptor();
        encryptOr.setConfig(cryptOr(password));
        String result = encryptOr.decrypt(value);
        return result;
    }

    /**
     * @param password salt
     * @return
     */
    public static SimpleStringPBEConfig cryptOr(String password) {
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(password);
        config.setAlgorithm("PBEWithMD5AndDES");
        config.setKeyObtentionIterations(1000);
        config.setPoolSize(1);
        // according Jasypt documentation, if no provider name is explicitly set, the default JVM provider will be used.
        config.setProviderName(null);
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setStringOutputType("base64");
        return config;
    }
# 将配置文件中的明文替换为生成的密文
# 注意,密文必须用ENC包起来
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/shares?autoReconnect=true&serverTimeZone=GMT&useSSL=false&rewriteBatchedStatements=true&useUnicode=true&characterEncoding=utf8
    username: ENC(Pta+24ztk+/o8HJs0pCjjQ==)
    password: ENC(0rL9fNGHs5Sbzp+L5r+yjA==)

其他

使用jasypt jar 包来生成密文

  • 直接使用命令对明文进行加密
    java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="123456" password=turing algorithm=PBEWithMD5AndDES
  • 直接使用命令对密文进行解密
    java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input="KCQCruXa2BN+StcKVPlkAg==" password=turing algorithm=PBEWithMD5AndDES

通过配置环境变量来传递密码

jasypt:
  encryptor:
    password: ${JASYPT_PASSWORD}

通过启动参数传递密码

  • java -jar -Djasypt.encryptor.password=G0CvDz7oJn6 xxx.jar
  • java -jar xxx.jar --jasypt.encryptor.password=turing