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.
This commit is contained in:
Yi EungJun
2020-01-14 08:13:26 +09:00
committed by Spencer Gibb
parent 4c7b8dfc7e
commit 75f3bbcff1
2 changed files with 22 additions and 3 deletions

View File

@@ -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<String, String> 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);
}
}

View File

@@ -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.<String, String>emptyMap());
TextEncryptor encryptor2 = this.locator.locate(Collections.<String, String>emptyMap());
assertThat(encryptor1).isEqualTo(encryptor2);
}
}