Spring Boot整合Jasypt增强应用安全

前言

Jasypt是一个Java库,允许开发人员以很简单的方式添加基本加密功能,而无需深入研究加密原理。利用它可以实现高安全性的,基于标准的加密技术,无论是单向和双向加密。加密密码,文本,数字,二进制文件…

开发工具以及依赖版本信息

Maven 3.5.0
JDK 1.8.0
Spring Boot 2.1.1-RELEASE
jasypt-spring-boot-starter 2.0.0

整合步骤

一、加入依赖

      
            com.github.ulisesbocchio
            jasypt-spring-boot-starter
            2.0.0
        

二、 配置jasypt的加密密码

在application.properties中配置加密需要使用的密钥。

jasypt.encryptor.password=EbfYk

三、加密内容

编写一个单元测试加密你需要加密的内容。

 @Autowired
    StringEncryptor jasyptStringEncryptor;
    @Test
    public void encrypt() {
        System.out.println("encrypt: " + jasyptStringEncryptor.encrypt("root"));
    }
    @Test
    public void decrypt() {
        System.out.println("decrypt: " + jasyptStringEncryptor.decrypt("o9uLVKcJV4C7SkdF9sZJzQ=="));
    }

四、修改配置信息

在application.properties中修改对应的参数信息

# 数据库基本配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=Asia/Shanghai
spring.datasource.username=ENC(o9uLVKcJV4C7SkdF9sZJzQ==)
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

进一步增强安全性

通过上面的步骤,已经能在一定程度上保证安全性了,但是如果配置文件泄露就会造成加密密码的泄露,因此可以进行自定义加密的规则,即使不小心泄露配置文件,也可以保证安全性。
配置信息类 JasyptConfiguration .java

import org.jasypt.encryption.StringEncryptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyDetector;

/**
* @author Jackieonway
* @version \$Id: JasyptConfiguration.java, v 0.1 2019-07-30 9:22 Jackieonway Exp $$
*/
@Configuration
public class JasyptConfiguration {

   @Bean("jasyptStringEncryptor")
   public StringEncryptor stringEncryptor(Environment environment){
   	return new MyJasyptStringEncryptor(environment);
   }
}

加解密类 JasyptStringEncryptor.java

import java.nio.charset.StandardCharsets;
import java.util.UUID;

import org.jasypt.contrib.org.apache.commons.codec_1_3.binary.Base64;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.StandardPBEByteEncryptor;
import org.jasypt.encryption.pbe.config.PBEConfig;
import org.jasypt.encryption.pbe.config.SimplePBEConfig;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;

/**
 * @author Jackieonway
 * @version \$Id: JasyptStringEncryptor.java, v 0.1 2019-07-30 9:48 Jackieonway Exp $$
 */
public class JasyptStringEncryptor implements StringEncryptor {

	private static final Logger log = LoggerFactory.getLogger(JasyptStringEncryptor.class);

	private final StandardPBEByteEncryptor byteEncryptor;
	private final Base64 base64;

	public JasyptStringEncryptor() {
		SimpleStringPBEConfig config = new SimpleStringPBEConfig();
		config.setPassword("EdLKOREFDMI/sddnc@A");
		config.setAlgorithm("PBEWithMD5AndDES");
		this.byteEncryptor = new StandardPBEByteEncryptor();
		this.byteEncryptor.setConfig(config);
		this.base64 = new Base64();
	}

	public JasyptStringEncryptor(Environment environment) {
		byteEncryptor = new StandardPBEByteEncryptor();
		byteEncryptor.setConfig(getConfig(environment));
		this.base64 = new Base64();
	}

	public JasyptStringEncryptor(String password) {
		SimplePBEConfig config = new SimplePBEConfig();
		config.setAlgorithm("PBEWithMD5AndDES");
		config.setPassword(password);
		byteEncryptor = new StandardPBEByteEncryptor();
		byteEncryptor.setConfig(config);
		this.base64 = new Base64();
	}

	public JasyptStringEncryptor(SimpleStringPBEConfig config) {
		byteEncryptor = new StandardPBEByteEncryptor();
		byteEncryptor.setConfig(config);
		this.base64 = new Base64();
	}

	@Override
	public String encrypt(String s) {
		byte[] encrypt = byteEncryptor.encrypt((s).getBytes());
		byte[] encode = base64.encode(encrypt);
		return new String(encode,StandardCharsets.UTF_8);
	}

	@Override
	public String decrypt(String s) {
		byte[] decode = base64.decode(s.getBytes());
		byte[] decrypt  = byteEncryptor.decrypt(decode);
		return new String(decrypt,StandardCharsets.UTF_8);
	}
	private PBEConfig getConfig(Environment e){
		SimpleStringPBEConfig config = new SimpleStringPBEConfig();
		config.setPassword(getRequiredProperty(e, "jasypt.encryptor.password"));
		config.setAlgorithm(getProperty(e, "jasypt.encryptor.algorithm", "PBEWithMD5AndDES"));
		config.setKeyObtentionIterations(getProperty(e, "jasypt.encryptor.keyObtentionIterations", "1000"));
		config.setPoolSize(getProperty(e, "jasypt.encryptor.poolSize", "1"));
		config.setProviderName(getProperty(e, "jasypt.encryptor.providerName", null));
		config.setSaltGeneratorClassName(getProperty(e, "jasypt.encryptor.saltGeneratorClassname", "org.jasypt.salt.RandomSaltGenerator"));
		config.setStringOutputType(getProperty(e, "jasypt.encryptor.stringOutputType", "base64"));
		return config;
	}

	private static String getProperty(Environment environment, String key, String defaultValue) {
		if (!propertyExists(environment, key)) {
			log.info("Encryptor config not found for property {}, using default value: {}", key, defaultValue);
		}
		return environment.getProperty(key, defaultValue);
	}

	private static boolean propertyExists(Environment environment, String key) {
		return environment.getProperty(key) != null;
	}

	private static String getRequiredProperty(Environment environment, String key) {
		if (!propertyExists(environment, key)) {
			throw new IllegalStateException(String.format("Required Encryption configuration property missing: %s", key));
		}
		return environment.getProperty(key);
	}

}

如果不想使用jasypt提供的前缀和后缀,使用下面的代码将原来的替换成您想要使用的任何前后缀

jasypt.encryptor.property.prefix=TEST(
jasypt.encryptor.property.suffix=)

觉得还是有可能因为加密密码造成泄漏,那么可以使用启动参数形式* --jasypt.encryptor.password=*

 java -jar xxx.jar --jasypt.encryptor.password=xxx

还可以使用环境变量的形式来获取加密密码

  #设置环境变量:

  # 打开/etc/profile文件

  vim /etc/profile

  # 文件末尾插入

  export JASYPT_PASSWORD = xxxx

  #启动命令:

  java -jar xxx.jar --jasypt.encryptor.password=${JASYPT_PASSWORD}

小结

经过上述一顿胡乱操作之后,Spring Boot整合Jasypt就成功啦,您的应用就可以更加安全的运行了

你可能感兴趣的:(Java,Spring,Boot)