Config Server——配置内容的加密与解密 详解
我们在Git仓库中存储的都是明文,但在很多场景下,某些敏感的配置内容(例如数据库账号、密码),应当被加密存储以提高安全性。Config Server为配置内容的加密与解密提供了支持。
安装JCE
Config Server的加解密功能依赖Java Cryptography Extension(JCE)。
Java 8 JCE的地址是:http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html 。
下载JCE,解压后,按照README.txt的说明即可安装,其实就是将JDK/jre/lib/security目录中的两个jar文件替换为JCE中的jar文件。
其他Java版本的JCE的下载地址及安装在Spring Cloud 文档中有提及,详见:http://cloud.spring.io/spring-cloud-static/Camden.SR2/#_cloud_native_applications
加解密端点
Config Server为我们提供了加密与解密的端点,分别是/encrypt
与 /decrypt
。我们可使用
curl $CONFIG_SERVER_URL/encrypt -d 想要加密的明文
来加密明文。使用
curl $CONFIG_SERVER_URL/decrypt -d 想要解密的密文
来解密密文。
编写代码
(1) 复制项目microservice-config-server
,将ArtifactId修改为microservice-config-server-encryption
。
(2) 修改application.yml,添加以下内容:
encrypt: key: foo # 设置对称密钥
这样,代码就编写完成了。
测试
(1) 输入命令
curl http://localhost:8080/encrypt -d mysecret
返回851a6effab6619f43157a714061f4602be0131b73b56b0451a7e268c880daea3
。说明mysecret
被加密了。
(2) 输入命令
curl http://localhost:8080/decrypt -d 851a6effab6619f43157a714061f4602be0131b73b56b0451a7e268c880daea3
可返回mysecret
,说明能够正常解密。
存储加密的内容
加密后的内容,使用{cipher}密文
的形式存储。
测试:
(1) 准备一个配置文件,命名为encryption.yml
spring: datasource: username: dbuser password: '{cipher}851a6effab6619f43157a714061f4602be0131b73b56b0451a7e268c880daea3'
并将其push到Git仓库https://git.oschina.net/itmuch/spring-cloud-config-repo。此处需注意spring.datasource.password上的单引号不能少。如果使用的是properties则无需使用单引号,例如:
spring.datasource.username=dbuserspring.datasource.password={cipher}851a6effab6619f43157a714061f4602be0131b73b56b0451a7e268c880daea3
这是由yaml与properties的解析机制所决定的。
(2) 使用http://localhost:8080/encryption-default.yml 可获得以下结果:
profile: defaultspring: datasource: password: mysecret username: dbuser
说明Config Server能够自动地为我们解密配置内容。
一些场景下,我们可能想要让Config Server直接返回密文本身,而并非解密后的内容,这时可设置spring.cloud.config.server.encrypt.enabled=false
。这时可由Config Client自行解密。
非对称加密
上文中,我们讨论的加密方式是对称加密,Spring Cloud同样支持非对称加密。
(1) 复制项目microservice-config-server
,将ArtifactId修改为microservice-config-server-encryption-rsa
。
(2) 创建一个Key Store,并将生成的文件复制到项目的classpath下。
keytool -genkeypair -alias mytestkey -keyalg RSA -dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" -keypass changeme -keystore server.jks -storepass letmein
(3) 在application.yml中添加以下内容:
encrypt: keyStore: location: classpath:/server.jks # jks文件的路径 password: letmein # storepass alias: mytestkey # alias secret: changeme # keypass
这样我们使用命令curl http://localhost:8080/encrypt -d mysecret
,将会得到以下结果:
AQB38UyNckYzW64rvsaIhy0OV4MUmS7krdHrw+VLUdqXJ4ZVdZL8/ouwSOAYM+6MSjKvzmkaU8Iv2cQ5MWhlZhCrm0f0d2ubc1MH96KBHTix9AroajeTiofPwPoBnWfBo9cC4PU1vD+rcvAvwvdR5q7rYbFc4yut4uJZRzpAXGgf680kAtb6tEtLx7c4/35PEaGXFWd2m8gn21vzWdvhbP6cdC9YlburL0Rq/0H1G+uEX99ZVIWJ0hVn4rplLWPMLUGA2ZVEyVRorIRX/2z5MU7cVPtJ6X1JZDpU4GVz8/3rD5BnbVFTGo6DfBrEzJn58Bzjl6aqo9ca/3j42RHOoQDOHXGqRX/843RbPdvMqTZd0rTOBHTUrVG9E15sCajiLkw=
相对于对称加密,非对称加密的安全性更高,但对称加密相对方便。读者可按照需求自行选择。
拓展阅读
http://stackoverflow.com/questions/30131598/spring-cloud-config-server-where-to-set-encrypt-key-to-enable-encrypt-endpoinhttps://juliomunoz.wordpress.com/2014/12/10/probando-spring-netflix-parte-1-spring-cloud-config-server/
- ASP.NET Core的配置(5):配置的同步[ 实例篇]
- TensorFlow 深度学习笔记 卷积神经网络
- 利用EntLib授权机制实现对ASP.NET页面的自动授权
- ASP.NET Core的配置(5):配置的同步[设计篇]
- 详解Redis内部运作机制
- TensorFlow深度学习笔记 循环神经网络实践
- 从客户端Web应用程序访问Bluemix服务
- 云改变传统银行业面貌的5种方式
- ASP.NET MVC中的ActionFilter是如何执行的?
- C语言嵌入式系统编程修炼之屏幕操作
- max-width:100%在td或者table-cell里渲染不符合预期小笔记
- ASP.NET Core中的依赖注入(2):依赖注入(DI)
- 使用Ansible自动化您的(云或者本地)机器
- 像Apache Storm一样简单的分布式图计算
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Cypress系列(45)- cypress-skip-and-only-ui 插件详解
- 多线程基础(五):java对象的MarkWord及synchronized锁升级过程
- 【每日一题】45. Jump Game II
- 「Elasticsearch + Lucene」搜索引擎的架构、倒排索引和搜索过程
- 查看 MAC JDK默认安装路径 JAVA路径 的shell 命令
- Gradle 命令行介紹和安裝教程
- Spring工厂创建复杂对象
- Nginx反向代理配置去除前缀
- 深入浅出java虚拟机
- Maven resources 分环境
- JetBrains Upsource(上源) 研究
- Spring JPA 拓展
- python自学成才之路 死锁的解决方案
- C++核心准则T.40: 使用函数对象向算法传递操作
- web页面性能优化总结及原理解释