美文网首页
Springboot项目中应用jasypt进行加解密

Springboot项目中应用jasypt进行加解密

作者: moutory | 来源:发表于2021-12-28 20:03 被阅读0次

    前言

    对于大部分项目来说,为了运维方便和项目解耦,往往会将一些和代码无关的配置抽离出来,单独放在一个配置文件中进行维护。但这类配置文件中常常含有密码等比较敏感的信息。为了避免出现敏感信息泄露等问题,采用加密等手段来增强项目的安全性是比较有必要的。本篇文章将以jasypt这个应用较为广泛的第三方依赖来进行讲解,主要基于Springboot进行应用。

    一、基于Springboot项目使用jasypt进行加解密

    (一)引入依赖

    jasypt对应Springboot项目有着良好的支持,可以省略我们对工具类的封装。使用jasypt需要在项目中引入如下依赖:

    <!-- spring-boot项目的依赖 -->
    <dependency>
        <groupId>com.github.ulisesbocchio</groupId>
        <artifactId>jasypt-spring-boot-starter</artifactId>
        <version>3.0.3</version>
    </dependency>
    
    (二)配置jasypt响应的加密配置

    对于加密秘钥的话,最好是不要写在配置文件中,不然别人根据你的配置就可以轻而易举地进行反推,敏感信息的加密程度就大大降低了。

    jasypt:
      encryptor:
        #默认加密算法:PBEWITHHMACSHA512ANDAES_256,sha512+AES算法,安全性更高,但是需要 Java JDK 1.9+
        #本服务使用jdk1.8,所以使用 PBEWithMD5AndDES md5+des算法
        #默认使用 com.ulisesbocchio.jasyptspringboot.encryptor.DefaultLazyEncryptor 进行加解密 ,PooledPBEStringEncryptor可以对其加密的内容进行解密
        algorithm: PBEWithMD5AndDES
        # 加密密钥,使用方式 spring.datasource.password=ENC(密文),不要设置在配置文件中,建议使用环境变量或者启动参数: --jasypt.encryptor.password=123456
        password: 123456
        #设置密文前缀和后缀
        property:
          prefix: ENC(
          suffix: )
        iv-generator-classname: org.jasypt.iv.RandomIvGenerator
    

    除了上面的配置项之外,还有如下配置项可选

    Key Required Default Value
    jasypt.encryptor.password True -
    jasypt.encryptor.algorithm False PBEWITHHMACSHA512ANDAES_256
    jasypt.encryptor.key-obtention-iterations False 1000
    jasypt.encryptor.pool-size False 1
    jasypt.encryptor.provider-name False SunJCE
    jasypt.encryptor.provider-class-name False null
    jasypt.encryptor.salt-generator-classname False org.jasypt.salt.RandomSaltGenerator
    jasypt.encryptor.iv-generator-classname False org.jasypt.iv.RandomIvGenerator
    jasypt.encryptor.string-output-type False base64
    jasypt.encryptor.proxy-property-sources False false
    jasypt.encryptor.skip-property-sources False empty list
    (三)在代码中进行测试

    注意,在代码测试之前,需要保证springboot项目中有正常使用@SpringBootApplication 或者@EnableAutoConfiguration注解
    我们可以项目中使用@Value注解来直接获取解密后的配置值

    步骤一:在配置文件中新增一个加密的配置

    注意,需要在密文外面使用我们前面定义的前缀和后缀进行包裹,这样jasypt才会识别到这个配置属于需要加密的配置。我们上面配置的jasypt.property.prefixjasypt.property.suffix分别是ENC() (也是默认的前后缀)。至于加密后的值是怎么来的,后文会介绍一个工具类。

    test:
      myvalue: ENC(zRDyVMf2i8Ek8nYJKBzHv2oG3oOgPlYw)
    
    步骤二:在代码中使用@Value注解来获取解密后的值
    @SpringBootTest(classes = DemoApplication.class)
    class DemoApplicationTests {
    
        @Value("${test.myvalue}")
        private String value;
    
        @Test
        public void utilsTest(){
           System.out.println("value:"+value);
        }
    }
    
    步骤三:运行代码,观察结果
    image.png

    我们可以看到,配置被成功的解密了出来。当然,在解密之前,我们需要先对配置文件进行加密一下才可以,在springboot项目中,我们可以十分简单地引用一个工具类StringEncryptor来进行加解密。
    我们可以简单使用这个工具类来进行一些测试:

    @Component
    public class EncryptorBootUtils {
        @Autowired
        private StringEncryptor stringEncryptor;
    
        public void testEncryptor(String msg) {
            System.out.println("原始的信息为"+ msg);
            // 下面的方法是加密
            String encryptStr = stringEncryptor.encrypt(msg);
            System.out.println("加密后的信息为"+encryptStr);
            // 下面的方法是解密
            String decrypt = stringEncryptor.decrypt("解密后的信息为"+encryptStr);
            System.out.println(decrypt);
        }
    
    }
    
    @SpringBootTest(classes = DemoApplication.class)
    class DemoApplicationTests {
    
        @Autowired
        private EncryptorBootUtils bootUtils;
    
        @Test
        public void utilsTest(){
           //System.out.println("value:"+value);
            bootUtils.testEncryptor("AABBCCD");
        }
    
    }
    
    
    工具类测试结果如下:
    image.png

    二、非Springboot项目使用jasypt进行加解密

    (一)引入依赖

    需要注意的是,非Springboot项目使用jasypt依赖和Springboot项目的不同。

    <dependency>
        <groupId>org.jasypt</groupId>
        <artifactId>jasypt</artifactId>
        <version>1.9.3</version>
     </dependency>
    
    (二)定义一个加解密的工具类

    项目中可能有很多地方需要用到加解密,所以我们最好把它封装成一个工具类:

    public class JasyptUtils {
        /**
         * 通过秘钥和字符串,获取加密后的字符串
         * @param secretKey
         * @param message
         * @return
         */
        public static String encrypt(String secretKey,String message){
            return stringEncryptor(secretKey,message,true);
        }
    
        /**
         * 通过秘钥和字符串,获取加密后的字符串
         * @param secretKey
         * @param message
         * @return
         */
        public static String decrypt(String secretKey,String message){
            return stringEncryptor(secretKey,message,false);
        }
        /**
         * {@link EncryptorBootUtils} 加解密。
         * 同一个密钥(secretKey)对同一个内容执行加密,生成的密文都是不一样的,但是根据根据这些密文解密成明文都是可以.
         * 1、Jasypt 默认使用 {@link EncryptorBootUtils} 来解密全局配置文件中的属性,所以提供密文时,也需要提供 {@link EncryptorBootUtils} 加密的密文
         * 2、{@link EncryptorBootUtils} 接口有很多的实现类,比如常用的 {@link PooledPBEStringEncryptor}
         * 3、setConfig(final PBEConfig config):为对象设置 {@link PBEConfig} 配置对象
         * 4、encrypt(final String message):加密内容
         * 5、decrypt(final String encryptedMessage):解密内容
         *
         * @param secretKey :密钥。加/解密必须使用同一个密钥
         * @param message   :加/解密的内容
         * @param isEncrypt :true 表示加密、false 表示解密
         * @return
         */
        private static String stringEncryptor(String secretKey, String message, boolean isEncrypt) {
            PooledPBEStringEncryptor pooledPBEStringEncryptor = new PooledPBEStringEncryptor();
            pooledPBEStringEncryptor.setConfig(getSimpleStringPBEConfig(secretKey));
            String result = isEncrypt ? pooledPBEStringEncryptor.encrypt(message) : pooledPBEStringEncryptor.decrypt(message);
            return result;
        }
    
        /**
         * 设置 {@link PBEConfig} 配置对象,SimpleStringPBEConfig 是它的实现类
         * 1、所有的配置项建议与全局配置文件中的配置项保持一致,特别是 password、algorithm 等等选项,如果不一致,则应用启动时解密失败而报错.
         * 2、setPassword(final String password):设置加密密钥,必须与全局配置文件中配置的保存一致,否则应用启动时会解密失败而报错.
         * 3、setPoolSize(final String poolSize):设置要创建的加密程序池的大小.
         * 4、setAlgorithm(final String algorithm): 设置加密算法的值, 此算法必须由 JCE 提供程序支持
         * 5、setKeyObtentionIterations: 设置应用于获取加密密钥的哈希迭代次数。
         * 6、setProviderName(final String providerName):设置要请求加密算法的安全提供程序的名称
         * 7、setSaltGeneratorClassName:设置 Sal 发生器
         * 8、setIvGeneratorClassName:设置 IV 发生器
         * 9、setStringOutputType:设置字符串输出的编码形式。可用的编码类型有 base64、hexadecimal
         *
         * @param secretKey
         * @return
         */
        private static SimpleStringPBEConfig getSimpleStringPBEConfig(String secretKey) {
            SimpleStringPBEConfig config = new SimpleStringPBEConfig();
            config.setPassword(secretKey);
            config.setAlgorithm("PBEWithMD5AndDES");
            //以下都是默认值
            config.setPoolSize("1");
            config.setKeyObtentionIterations("1000");
            config.setProviderName("SunJCE");
            config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
            //命令行执行时要指定这个参数
            config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
            config.setStringOutputType("base64");
            return config;
        }
    
    }
    

    当我们需要使用时,只需要传入秘钥,调用工具类中对应加解密方法即可。

    本篇文章到此就介绍完了,希望可以让各位读者快速入门。需要注意的是,jasypt这个第三方组件内还包含着相当丰富的功能(诸如插件、命令行加解密),有兴趣想要更深入了解的话,可以访问jasypt的GitHub官方网址:https://github.com/ulisesbocchio/jasypt-spring-boot

    参考文章:
    SpringBoot配置文件属性加密:https://www.jianshu.com/p/7eed4e4fb3ba

    相关文章

      网友评论

          本文标题:Springboot项目中应用jasypt进行加解密

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