怎么在SpringBoot 配置文件进行加密

发布时间:2021-03-18 17:09:44 作者:Leah
来源:亿速云 阅读:256

本篇文章为大家展示了怎么在SpringBoot 配置文件进行加密,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

首先需要确定一个加密解密方式,本文采用 RSA 进行加密解密,首先编写加密解密的代码,注意RSA加密解密需要使用到公钥和私钥,公钥私钥的生成代码如下:

public static void generateKey() throws NoSuchAlgorithmException {
  KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(EncryptionType.RSA);
  keyPairGen.initialize(1024, new SecureRandom());
  KeyPair keyPair = keyPairGen.generateKeyPair();
  RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  // 得到私钥
  RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥
  String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
  String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
  System.out.println("当前生成的公钥= " + publicKeyString);
  System.out.println("当前生成的私钥= " + privateKeyString);
}

加密代码如下:

public static String encrypt(String str, String publicKey) throws NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException {
		byte[] decoded = Base64.decodeBase64(publicKey);
		RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(EncryptionType.RSA).generatePublic(new X509EncodedKeySpec(decoded));
		Cipher cipher = Cipher.getInstance(EncryptionType.RSA);
		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
		return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
	}

解密代码如下:

public static String decrypt(String str, String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
  byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
  byte[] decoded = Base64.decodeBase64(privateKey);
  RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(EncryptionType.RSA).generatePrivate(new PKCS8EncodedKeySpec(decoded));
  Cipher cipher = Cipher.getInstance(EncryptionType.RSA);
  cipher.init(Cipher.DECRYPT_MODE, priKey);
  return new String(cipher.doFinal(inputByte));
}

上述代码为基本的加密解密工具,加下来需要在配置文件中确定哪些配置是需要进行解密的,本例将采用自定义前缀+后缀的方式进行匹配,前缀为 PWD[ ,后缀为 ] ,如果在配置文件中属性值是以前缀后缀包裹的那么这个数据会被进行解密操作,

通过前文的加密工具可以先进行一次密码加密加密原文为 1234qwer ,公钥:

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCBOkkkvjbOQ6UTCo8U4bRC/EcEtxz8haHg6lueM3NBbH3eIT7kfwQFOqj1h2qPGcQNeyn4vxzMWBAKzSQehjqVBL7/8GN7EZ7TEaUuWO+8qsuZnOdrztX7bNKACnks+SelmtbrbnFKUMAq2c2mS0o1V6iwyRxJYLGaHGXnz4KSkwIDAQAB

私钥:

MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIE6SSS+Ns5DpRMKjxThtEL8RwS3HPyFoeDqW54zc0Fsfd4hPuR/BAU6qPWHWo8ZxA17Kfi/HMxYEArNJB6GOpUEvv/wY3sRntMRpS5Y77yqy5mc52vO1fts0oAKeSz5J6Wa1utucUpQwCrZzaZLSjVXqLDJHElgsZocZefPgpKTAgMBAAECgYAFaCDjTqoQWzgu4cQ2xXK7Ur7N7bNixVyOgn+u0MxDsnxZrN5qxP2wElI7Y5xgXF2diseoxqY3zn9tVEPsmwUcY73naoosx9V8oExgT/BUkZYIzj1ei08zOr984zl3dbFcxOCRvqywXj9FAAGx1mhmCzFCIauJg3aX0S9mt5/CwQJBAMYZsmMQ9owoXZuSclKVRfMHFpAPhQlcBM4xadhX0IRYATgNTxpESmcCoGWvyw3bvieNJyC9Njx6X4FJ2EZUzhECQQCm/2IM5MlsCwyKtME5RPFna2hSqYU80UzkNfDIyMokcU2JUI4Fhigog4ol0GFMiMBsHIjS+cJiAwNbIsq5rsJjAkA94yVBobkETFACHBwvBIdXxy0bUF3lcKPnrrQ8bCKuVbf7xNyjfhYoXD+zxNmQuMeNH6HLrpDVD/3qLCGuxyuhAkAiLPl/8gJWnhw+9qbkdXuB0rVS1WZy/9JgkblpHc5gjt9zTo0CDGaDhAftnSuMYiAe/+fwZTSmoj85k3ExdtZJAkEArJuG/NWY9HP4p7jtZX9rMokyB3517v7HQdJKBDIlOzseRC/roCvU8LQ/URDFBUqXCRgedxgW+0ZmKFf4xeawqw==

加密结果为:

PWD[bMw8oqC/ma31JqF0DCuf5QWqSFRMigYw3fMBIIIfJ85vnmNnFbH9IcJfUHgbSmNHeITffToODwAygy4vKdzu6o1i1UQOd8w4nPKhnVJCLKqW5jmc3Yw+FkTIRBp63NJWzECVnRHqEK+bTxPMa1gfKql/2U45XxqeDSZOEXGeA+E=]

得到这个数据后将其配置在 application.properties 文件中,具体内容如下

server.port=8080
spring.application.name=test-app
spring.datasource.password=PWD[bMw8oqC/ma31JqF0DCuf5QWqSFRMigYw3fMBIIIfJ85vnmNnFbH9IcJfUHgbSmNHeITffToODwAygy4vKdzu6o1i1UQOd8w4nPKhnVJCLKqW5jmc3Yw+FkTIRBp63NJWzECVnRHqEK+bTxPMa1gfKql/2U45XxqeDSZOEXGeA+E=]

接下来需要进一步解决的是如何将这个加密字符串进行解密,这里需要使用 BeanFactoryPostProcessor 接口对环境变量进行修改,具体实现代码如下:

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

  MutablePropertySources propertySources = environment.getPropertySources();

  for (PropertySource<?> propertySource : propertySources) {
   if (propertySource instanceof OriginTrackedMapPropertySource
   ) {
     OriginTrackedMapPropertySource om = (OriginTrackedMapPropertySource) propertySource;
     Map<String, Object> source = om.getSource();
     source.forEach((k, v) -> {
      String property = environment.getProperty(k);
      if (hasPreAndSuf(property)) {
        LOG.info("开始处理 k = [{}]", k);
        try {
         String relay = splitPreAndSuf(property, this.prefix, this.suffix);
         String decrypt = RSAEncrypt.decrypt(relay, getPrivateKey(environment));
         source.put(k, decrypt);
        }
        catch (Exception e) {
         LOG.error("e = ", e);
        }
      }
     });
   }
  }
}

处理逻辑如下:

  1. 提取环境配置中的所有配置属性

  2. 判断配置属性是否是 OriginTrackedMapPropertySource 类型,该类型的数据是在 application.yaml 中的内容

  3. 处理 OriginTrackedMapPropertySource 对象的value值,如果value包含自定义前缀后缀则进行解密

在本例中对于公钥私钥以及前缀后缀是允许自定义的,开发者只需要在配置文件中根据下面表格进行填写即可

属性名称属性含义默认值
encryption.prefix前缀PWD[
encryption.suffix后缀]
encryption.rsa.publicKey公钥
encryption.rsa.privateKey私钥

注意:**为了便捷操作开放了配置文件形式的公钥秘钥的配置,这部分配置可以在测试环境中开发环境中进行使用。**如果需要在生产环境中使用请使用下面两种方式:

方式一:在项目资源目录 resources 文件夹下创建 hf_private_key 文件,向文件中填写如下内容

encryption.rsa.privateKey=MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIE6SSS+Ns5DpRMKjxThtEL8RwS3HPyFoeDqW54zc0Fsfd4hPuR/BAU6qPWHWo8ZxA17Kfi/HMxYEArNJB6GOpUEvv/wY3sRntMRpS5Y77yqy5mc52vO1fts0oAKeSz5J6Wa1utucUpQwCrZzaZLSjVXqLDJHElgsZocZefPgpKTAgMBAAECgYAFaCDjTqoQWzgu4cQ2xXK7Ur7N7bNixVyOgn+u0MxDsnxZrN5qxP2wElI7Y5xgXF2diseoxqY3zn9tVEPsmwUcY73naoosx9V8oExgT/BUkZYIzj1ei08zOr984zl3dbFcxOCRvqywXj9FAAGx1mhmCzFCIauJg3aX0S9mt5/CwQJBAMYZsmMQ9owoXZuSclKVRfMHFpAPhQlcBM4xadhX0IRYATgNTxpESmcCoGWvyw3bvieNJyC9Njx6X4FJ2EZUzhECQQCm/2IM5MlsCwyKtME5RPFna2hSqYU80UzkNfDIyMokcU2JUI4Fhigog4ol0GFMiMBsHIjS+cJiAwNbIsq5rsJjAkA94yVBobkETFACHBwvBIdXxy0bUF3lcKPnrrQ8bCKuVbf7xNyjfhYoXD+zxNmQuMeNH6HLrpDVD/3qLCGuxyuhAkAiLPl/8gJWnhw+9qbkdXuB0rVS1WZy/9JgkblpHc5gjt9zTo0CDGaDhAftnSuMYiAe/+fwZTSmoj85k3ExdtZJAkEArJuG/NWY9HP4p7jtZX9rMokyB3517v7HQdJKBDIlOzseRC/roCvU8LQ/URDFBUqXCRgedxgW+0ZmKFf4xeawqw==

需要将等于号后面的内容进行修改,替换为项目中的秘钥

方式二:通过命令行进行传递

在启动命令中添加

-Dencryption.rsa.privateKey=MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIE6SSS+Ns5DpRMKjxThtEL8RwS3HPyFoeDqW54zc0Fsfd4hPuR/BAU6qPWHWo8ZxA17Kfi/HMxYEArNJB6GOpUEvv/wY3sRntMRpS5Y77yqy5mc52vO1fts0oAKeSz5J6Wa1utucUpQwCrZzaZLSjVXqLDJHElgsZocZefPgpKTAgMBAAECgYAFaCDjTqoQWzgu4cQ2xXK7Ur7N7bNixVyOgn+u0MxDsnxZrN5qxP2wElI7Y5xgXF2diseoxqY3zn9tVEPsmwUcY73naoosx9V8oExgT/BUkZYIzj1ei08zOr984zl3dbFcxOCRvqywXj9FAAGx1mhmCzFCIauJg3aX0S9mt5/CwQJBAMYZsmMQ9owoXZuSclKVRfMHFpAPhQlcBM4xadhX0IRYATgNTxpESmcCoGWvyw3bvieNJyC9Njx6X4FJ2EZUzhECQQCm/2IM5MlsCwyKtME5RPFna2hSqYU80UzkNfDIyMokcU2JUI4Fhigog4ol0GFMiMBsHIjS+cJiAwNbIsq5rsJjAkA94yVBobkETFACHBwvBIdXxy0bUF3lcKPnrrQ8bCKuVbf7xNyjfhYoXD+zxNmQuMeNH6HLrpDVD/3qLCGuxyuhAkAiLPl/8gJWnhw+9qbkdXuB0rVS1WZy/9JgkblpHc5gjt9zTo0CDGaDhAftnSuMYiAe/+fwZTSmoj85k3ExdtZJAkEArJuG/NWY9HP4p7jtZX9rMokyB3517v7HQdJKBDIlOzseRC/roCvU8LQ/URDFBUqXCRgedxgW+0ZmKFf4xeawqw==

需要将等号后面的内容进行修改,替换为项目中的秘钥

从笔者所经历的角度来看命令行传递参数可能更加安全一些,因为文件和命令行相比命令行需要在生产环境才可以看到,而文件在仓库中会存在。

接下来做一个测试,在启动时输出 spring.datasource.password 属性查看是否是加密前的数据,测试代码如下:

@SpringBootApplication
public class App {

  @Value("${spring.datasource.password}")
  private String dataSourceProperties;


  public static void main(String[] args) {
   SpringApplication.run(App.class, args);
  }

  @Bean
  public ApplicationRunner runner() {
   return args -> {
     System.out.println(dataSourceProperties);
   };
  }
}

启动项目后可以看到控制台输出

1234qwer

上述内容就是怎么在SpringBoot 配置文件进行加密,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

推荐阅读:
  1. 基于Jasypt对SpringBoot配置文件加密
  2. 怎么在Springboot中加密配置文件

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot

上一篇:怎么在docker中查看容器的挂载目录

下一篇:无线网络间歇性卡顿的原因是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》