Spring Cloud Config - RSA簡介以及使用RSA加密配置文件
簡介
RSA非對稱加密有著非常強大的安全性,HTTPS的SSL加密就是使用這種方法進行HTTPS請求加密傳輸的。因為RSA算法會涉及Private Key和Public Key分別用來加密和解密,所以稱為非對稱加密。Private Key和Public Key有互操作性,即用private key加密的可以用public key解密,用public key加密的可以用private key解密。傳統的單向認證則只用public key進行加密,有private key的一方才可進行解密。例如,一個web服務器會有一對private key和public key。瀏覽器客戶端保存著服務器的public key。當客戶端需要向服務器發送數據時,就用服務器的public key進行加密,然後服務器收到數據時,再用private key進行解密。客戶端驗證服務器是否為真實的服務器時,會根據服務器提供的public key和自己本地保存的public key作比較,一致的話才能驗證服務器的真實性。
在我們的config server中,一些對加密要求比較高的可以采用RSA算法進行數據的加密和解密。
項目源碼
Gitee碼雲
生成測試Keystore
我們需要使用jdk自帶的keytool
工具生成一個keystore,裏邊保存了private key的信息,使用如下命令行:
keytool -genkeypair -alias config-server-key -keyalg RSA -dname "CN=Config Server,OU=Xuqian,O=My Own Company,L=Beijing,S=Beijing,C=CN" -keypass changeit -keystore server.jks -storepass changeit
-genkeypair 參數即產生一對public key和private key。
-alias 指定key的別名,用於區分同一keystore中不同的key。
-keyalg 指定生成key的算法,這裏使用默認的RSA
-dname 指定common name,即CN,用以驗證key的身份。其中各項皆為自定義參數,OU為單位名稱,O為組織名稱,L為城市,S為省份/州,C為國家
-keypass 為key的密碼
-keystore 為keystore的文件名
-storepass 訪問keystore的密碼
上述工具將產生的 privte key 保存在了名為server.jks的 key store 中。到目前為止,我們只產生了 private key,Spring Cloud Config Server 會根據我們提供的 key 的信息,每次會用程序生成一個 public key,參考如下源代碼org.springframework.security.rsa.crypto.KeyStoreKeyFactory
public KeyPair getKeyPair(String alias, char[] password) {
try {
synchronized (lock) {
if (store == null) {
synchronized (lock) {
// 根據配置提供的 keystore 文件地址和密碼獲取 keystore 的實例對象
store = KeyStore.getInstance("jks");
store.load(resource.getInputStream(), this.password);
}
}
}
// 根據配置提供的 alias 和 password 從 keystore 中取得 private key
RSAPrivateCrtKey key = (RSAPrivateCrtKey) store.getKey(alias, password);
// 定義 Public Key 生成規則
RSAPublicKeySpec spec = new RSAPublicKeySpec(key.getModulus(),
key.getPublicExponent());
// 生成 Public Key
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(spec);
return new KeyPair(publicKey, key);
}
catch (Exception e) {
throw new IllegalStateException("Cannot load keys from store: " + resource, e);
}
}
這裏使用了 Java Security API 來對key進行操作。參見註釋。然後上邊的信息通過 configserver
中的 bootstrap.xml
配置文件提供:
encrypt:
#key: Thisismysecretkey
key-store:
location: file://${user.home}/development/keys/server.jks
password: changeit
alias: config-server-key
secret: changeit
因為我們不能同時使用對稱加密和非對稱加密,所以我們把 encrypt.key
配置註釋掉,然後指定非對稱加密的參數:
- location: Keystore 的文件路徑
- password: keystore 的密碼
- alias: key 的別名
- secret: key的密碼
測試
我們繼續使用 encrypt
API加密一項測試數據:
curl http://localhost:8888/encrypt -d 23456789
返回加密後的字符:
AQAPWOUOh4WVexGgVv+bgtKc5E0d5Aba8VUKnzEXh27HyKSAbW+wyzDwZTbk5QYfXpoCAs413rdeNIdR2ez44nkjT5V+438/VQExySzjZPhP0xYXi9YIaJqA3+Ji+IWK8hrGtJ4dzxIkmItiimCOirLdZzZGDm/yklMUVh7lARSNuMxXGKlpdBPKYWdqHm57ob6Sb0ivm4H4mL1n4d3QUCuE7hh2F4Aw4oln7XueyMkRPTtPy8OpnBEEZhRfmaL/auVZquLU5jjMNJk9JiWOy+DSTscViY/MZ+dypv6F4AfDdVvog89sNmPzcUT+zmB8jXHdjLoKy+63RG326WffY9OPuImW6/kCWZHV6Vws55hHqRy713W6yDBlrQ/gYC3Wils=
然後測試解密
curl http://localhost:8888/decrypt -d AQAPWOUOh4+bgtKc5E0d5Aba8VUKnzEXh27HyKSAbW+wyzDwZTbk5QYfXpoCAs413rdeNIdR2ez44nkjT5V+438/VQExySzjZPhP0xYXi9YIaJqA3+Ji+IWK8hrGtJ4dzxIkmItiimCOirLdZzZGDm/yklMUVh7lARSNuMxXGKlpdBPKYWdqHm57ob6Sb0ivm4H4mL1n4d3QUCuE7hh2F4Aw4oln7XueyMkRPTtPy8OpnBEEZhRfmaL/auVZquLU5jjMNJk9JiWOy+DSTscViY/MZ+dypv6F4AfDdVvog89sNmPzcUT+zmB8jXHdjLoKy+63RG326WffY9OPuImW6/kCWZHV6Vws55hHqRy713W6yDBlrQ/gYC3Wils=
會返回
23456789
我們還可以修改web-client.yml
來驗證:
#test:
#password: ‘{cipher}94c1027141add9844ec47f0be13caebb6b38ed1dcf99811b1a5cd2b874c64407‘
user:
password: ‘{cipher}AQAPWOUOh4WVexGgVv+bgtKc5E0d5Aba8VUKnzEXh27HyKSAbW+wyzDwZTbk5QYfXpoCAs413rdeNIdR2ez44nkjT5V+438/VQExySzjZPhP0xYXi9YIaJqA3+Ji+IWK8hrGtJ4dzxIkmItiimCOirLdZzZGDm/yklMUVh7lARSNuMxXGKlpdBPKYWdqHm57ob6Sb0ivm4H4mL1n4d3QUCuE7hh2F4Aw4oln7XueyMkRPTtPy8OpnBEEZhRfmaL/auVZquLU5jjMNJk9JiWOy+DSTscViY/MZ+dypv6F4AfDdVvog89sNmPzcUT+zmB8jXHdjLoKy+63RG326WffY9OPuImW6/kCWZHV6Vws55hHqRy713W6yDBlrQ/gYC3Wils=‘
註釋掉 test.password
,新增一個 user.password
使用加密後的配置值。然後提交的gitee倉庫,通過 url 訪問此配置文件:
http://localhost:8888/web-client/default
得到如下結果:
{
"name": "web-client",
"profiles": [
"default"
],
"label": null,
"version": "3044a5345fb86d09a043ca7404b9e57c8c13c512",
"state": null,
"propertySources": [
{
"name": "https://gitee.com/zxuqian/spring-cloud-config-remote/web-client.yml",
"source": {
"message": "此條消息來自於遠程配置倉庫",
"management.endpoints.web.exposure.include": "*",
"user.password": "23456789"
}
}
]
}
Spring Cloud Config - RSA簡介以及使用RSA加密配置文件