From 75f3bbcff115f0e21c841676f8b92f2eb3a8b0b0 Mon Sep 17 00:00:00 2001 From: Yi EungJun Date: Tue, 14 Jan 2020 08:13:26 +0900 Subject: [PATCH] Fix perf issue of KeyStoreTextEncryptorLocator (#1496) CipherEnvironmentEncryptor.decrypt() gets a TextEncryptor for each environment property by KeyStoreTextEncryptorLocator.locate() which calls KeyStoreKeyFactory.getKeyPair() to create an instance of RsaSecretEncrptor. Unfortunately KeyStoreKeyFactory.getKeyPair() seems extremely slow for jks files whose format is PKCS12. So we need not to repeat calling the method if possible. Reuse an intance of RsaSecretEncrptor to avoid the performance problem. --- .../KeyStoreTextEncryptorLocator.java | 19 ++++++++++++++++--- .../KeyStoreTextEncryptorLocatorTests.java | 6 ++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/encryption/KeyStoreTextEncryptorLocator.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/encryption/KeyStoreTextEncryptorLocator.java index abc1353a..ecc8bb05 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/encryption/KeyStoreTextEncryptorLocator.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/encryption/KeyStoreTextEncryptorLocator.java @@ -45,6 +45,8 @@ public class KeyStoreTextEncryptorLocator implements TextEncryptorLocator { private String defaultAlias; + private RsaSecretEncryptor defaultEncryptor; + private SecretLocator secretLocator = new PassthruSecretLocator(); private RsaAlgorithm rsaAlgorithm = RsaAlgorithm.DEFAULT; @@ -83,9 +85,20 @@ public class KeyStoreTextEncryptorLocator implements TextEncryptorLocator { public TextEncryptor locate(Map keys) { String alias = keys.containsKey(KEY) ? keys.get(KEY) : this.defaultAlias; String secret = keys.containsKey(SECRET) ? keys.get(SECRET) : this.defaultSecret; - return new RsaSecretEncryptor( - this.keys.getKeyPair(alias, this.secretLocator.locate(secret)), - this.rsaAlgorithm, this.salt, this.strong); + if (alias.equals(this.defaultAlias) && secret.equals(this.defaultSecret)) { + if (this.defaultEncryptor == null) { + this.defaultEncryptor = rsaSecretEncryptor(alias, secret); + } + return this.defaultEncryptor; + } + else { + return rsaSecretEncryptor(alias, secret); + } } + private RsaSecretEncryptor rsaSecretEncryptor(String alias, String secret) { + return new RsaSecretEncryptor( + this.keys.getKeyPair(alias, this.secretLocator.locate(secret)), + this.rsaAlgorithm, this.salt, this.strong); + } } diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/encryption/KeyStoreTextEncryptorLocatorTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/encryption/KeyStoreTextEncryptorLocatorTests.java index 422844de..aed9fe30 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/encryption/KeyStoreTextEncryptorLocatorTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/encryption/KeyStoreTextEncryptorLocatorTests.java @@ -71,4 +71,10 @@ public class KeyStoreTextEncryptorLocatorTests { assertThat(encryptor.decrypt(encryptor.encrypt("foo"))).isEqualTo("foo"); } + @Test + public void testDefaultEncryptor() { + TextEncryptor encryptor1 = this.locator.locate(Collections.emptyMap()); + TextEncryptor encryptor2 = this.locator.locate(Collections.emptyMap()); + assertThat(encryptor1).isEqualTo(encryptor2); + } }