美文网首页Spring boot 技术Java 杂谈it
Spring Boot整合Jasypt增强应用安全

Spring Boot整合Jasypt增强应用安全

作者: jackieonway | 来源:发表于2019-07-30 20:53 被阅读7次

    前言

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

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

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

    整合步骤

    一、加入依赖

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

    二、 配置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就成功啦,您的应用就可以更加安全的运行了

    相关文章

      网友评论

        本文标题:Spring Boot整合Jasypt增强应用安全

        本文链接:https://www.haomeiwen.com/subject/fhpnrctx.html