当前位置:   article > 正文

nacos&apollo配置中心自动化解密_nacos密码解密

nacos密码解密

背景

配置中心中的配置往往存在需要加密的配置,比如数据库用户名、密码等。由于项目中同时使用nacos&apollo,所以需要实现一下两种配置中心的自动化解密

1.封装jaspyt

1.1引用jar包

以jaspyt作为解密框架,这里jaspyt没有使用starter的原因是可能各项目springboot版本不同,可能存在兼容性问题。如果是新项目可以考虑使用统一版本的starter实现自动化解密

  1. <dependency>
  2. <groupId>org.jasypt</groupId>
  3. <artifactId>jasypt</artifactId>
  4. <version>1.9.3</version>
  5. </dependency>

1.2增加工具类

从网上找一个简单的工具类:

  1. /**
  2. * 需解密的标记头
  3. */
  4. private static final String ENCRYPTED_VALUE_PREFIX = "ENC(";
  5. /**
  6. * 需解密的标记尾
  7. */
  8. private static final String ENCRYPTED_VALUE_SUFFIX = ")";
  9. /**
  10. * 解密密码
  11. */
  12. public static final String JASYPT_PASSWORD = "xxx";
  13. /**
  14. * 判断是否是 prefixes/suffixes 包裹的属性
  15. *
  16. * @param value
  17. * @return
  18. */
  19. public static boolean isEncryptedValue(final String value) {
  20. if (value == null) {
  21. return false;
  22. }
  23. final String trimmedValue = value.trim();
  24. return (trimmedValue.startsWith(ENCRYPTED_VALUE_PREFIX) &&
  25. trimmedValue.endsWith(ENCRYPTED_VALUE_SUFFIX));
  26. }
  27. /**
  28. * 如果通过 prefixes/suffixes 包裹的属性,那么返回密文的值;如果没有被包裹,返回原生的值。
  29. *
  30. * @param value
  31. * @return
  32. */
  33. private static String getInnerEncryptedValue(final String value) {
  34. return value.substring(
  35. ENCRYPTED_VALUE_PREFIX.length(),
  36. (value.length() - ENCRYPTED_VALUE_SUFFIX.length()));
  37. }
  38. /**
  39. * Jasypt生成加密结果
  40. *
  41. * @param password 配置文件中设定的加密密码 jasypt.encryptor.password
  42. * @param value 待加密值
  43. * @return
  44. */
  45. public static String encryptPwd(String password, String value) {
  46. PooledPBEStringEncryptor encryptOr = new PooledPBEStringEncryptor();
  47. encryptOr.setConfig(cryptOr(password));
  48. return encryptOr.encrypt(value);
  49. }
  50. /**
  51. * 解密
  52. *
  53. * @param password 配置文件中设定的加密密码 jasypt.encryptor.password
  54. * @param value 待解密密文
  55. * @return
  56. */
  57. public static String decyptPwd(String password, String value) {
  58. PooledPBEStringEncryptor encryptOr = new PooledPBEStringEncryptor();
  59. encryptOr.setConfig(cryptOr(password));
  60. return encryptOr.decrypt(isEncryptedValue(value) ? getInnerEncryptedValue(value) : value);
  61. }
  62. /**
  63. * @param password salt
  64. * @return
  65. */
  66. public static SimpleStringPBEConfig cryptOr(String password) {
  67. SimpleStringPBEConfig config = new SimpleStringPBEConfig();
  68. config.setPassword(password);
  69. config.setAlgorithm(StandardPBEByteEncryptor.DEFAULT_ALGORITHM);
  70. config.setKeyObtentionIterations("1000");
  71. config.setPoolSize("1");
  72. config.setProviderName(null);
  73. config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
  74. config.setStringOutputType("base64");
  75. return config;
  76. }

2.apollo

2.1 引用jar包

使用了apollo的1.3的客户端:

  1. <dependency>
  2. <groupId>com.ctrip.framework.apollo</groupId>
  3. <artifactId>apollo-client</artifactId>
  4. <version>1.3.0</version>
  5. </dependency>
2.2 增加自动化解密功能

经过断点调试,发现apollo更新配置时都会经过这个方法:

修改如下,使用了jaspyt包中的加解密方法,实现了配置在同步后的自动化解密:

  1. Set<Object> keys = newConfigProperties.keySet();
  2. for (Object k : keys) {
  3. String key = k.toString();
  4. String value = newConfigProperties.getProperty(key);
  5. //判断是否是规则密文
  6. if (JasyptUtils.isEncryptedValue(value)) {
  7. try {
  8. // 解密然后重新赋值
  9. String decyptVal = JasyptUtils.decyptPwd(JasyptUtils.JASYPT_PASSWORD, value);
  10. newConfigProperties.setProperty(key, decyptVal);
  11. } catch (Exception e) {
  12. logger.error("错误信息是:{}, 错误堆栈是:{}", ExceptionUtil.getMessage(e),
  13. ExceptionUtil.stacktraceToString(e));
  14. }
  15. }
  16. }
2.3 在apollo中装配自定义模块

需要替换下面的模块实现配置自动解密:

新建一个相同的类,覆盖掉这个工厂类即可。最后通过apollo提供的spi接口com.ctrip.framework.apollo.internals.Injector替换掉这个模块装配器

3.nacos

3.1 引用jar包
  1. <dependency>
  2. <groupId>com.alibaba.cloud</groupId>
  3. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  4. <version>2021.1</version>
  5. </dependency>
3.2增加自动化解密功能

经过断点调试,发现nacos同步配置时都会经过这个方法:

该类是在这个配置器中自动装配的:

经过分析源码得知,这个配置器是通过springcloud上下文启动的,并且没有加@ConditionalOnMissingBean注解,在spring上下文中替换比较麻烦。所以最简便的方法是增加一个同名包和同名bean:

修改方法loadNacosDataIfPresent:

  1. private void loadNacosDataIfPresent(final CompositePropertySource composite,
  2. final String dataId, final String group, String fileExtension,
  3. boolean isRefreshable) {
  4. if (null == dataId || dataId.trim().length() < 1) {
  5. return;
  6. }
  7. if (null == group || group.trim().length() < 1) {
  8. return;
  9. }
  10. NacosPropertySource propertySource = this.loadNacosPropertySource(dataId, group, fileExtension, isRefreshable);
  11. Map<String, Object> source = propertySource.getSource();
  12. for (String key : source.keySet()) {
  13. String value = source.get(key).toString();
  14. if (JasyptUtils.isEncryptedValue(value)) {
  15. try {
  16. String decryptValue = JasyptUtils.decyptPwd(JasyptUtils.JASYPT_PASSWORD, value);
  17. source.put(key, decryptValue);
  18. } catch (Exception e) {
  19. log.error("nacos解密失败!请检察是否包含正确的密文:错误信息是:{}, 错误堆栈是:{}", ExceptionUtil.getMessage(e),
  20. ExceptionUtil.stacktraceToString(e));
  21. }
  22. }
  23. }
  24. this.addFirstPropertySource(composite, propertySource, false);
  25. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/733503
推荐阅读
相关标签
  

闽ICP备14008679号