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做比較,一致的話才能驗證服務器的真實性。java
在咱們的config server中,一些對加密要求比較高的能夠採用RSA算法進行數據的加密和解密。git
Gitee碼雲web
咱們須要使用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的密碼spring
上述工具將產生的 privte key 保存在了名爲server.jks的 key store 中。到目前爲止,咱們只產生了 private key,Spring Cloud Config Server 會根據咱們提供的 key 的信息,每次會用程序生成一個 public key,參考以下源代碼org.springframework.security.rsa.crypto.KeyStoreKeyFactory
:json
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
配置文件提供:bootstrap
encrypt: #key: Thisismysecretkey key-store: location: file://${user.home}/development/keys/server.jks password: changeit alias: config-server-key secret: changeit
由於咱們不能同時使用對稱加密和非對稱加密,因此咱們把 encrypt.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" } } ] }