I created a FIPS 140-2 Compliant Credential Store using the Bouncy Castle provider. As it is described in the documentation, first I created the secter key:
keytool -genseckey -alias key -keyalg AES -keysize 256 -keystore keystore.bcfks -storetype BCFKS -storepass myPass -keypass myPass
Then I created the crefential store like:
/subsystem=elytron/credential-store=myCredentialstore:add(relative-to=jboss.server.config.dir, credential-reference={clear-text=”${ENC::myResolver:myEncodedExpression}”}, implementation-properties={keyAlias=key, external=true, externalPath=credentialStore.bcfks, keyStoreType=BCFKS}, create=true, path=keystore.bcfks, modifiable=true)
The credential store works fine, but now I need to read a password from it programmatically. I found and tried two ways doing this.
Solution 1.
public static Password getpassword() throws CredentialStoreException {
Password storePassword = ClearPassword.createRaw(ClearPassword.ALGORITHM_CLEAR,
MY_CLEAR_PASSWORD.toCharArray());
ProtectionParameter protectionParameter = new CredentialSourceProtectionParameter(IdentityCredentials.NONE.withCredential(new PasswordCredential(storePassword)));
Provider bcProvider = new BouncyCastleFipsProvider();
Security.addProvider(bcProvider);
KeyStoreCredentialStore keyStoreCredentialStore = new KeyStoreCredentialStore();
Map<String, String> kscsConfiguration = new HashMap<>();
String keystorePath = "myPath/keystore.bcfks";
String externalPath = "myPath/credentialStore.bcfks";
kscsConfiguration.put("location", keystorePath);
kscsConfiguration.put("modifiable", "true");
kscsConfiguration.put("keyStoreType", "BCFKS");
kscsConfiguration.put("keyAlias", "key");
kscsConfiguration.put("external", "true");
kscsConfiguration.put("externalPath", externalPath);
Provider[] providers = { bcProvider };
keyStoreCredentialStore.initialize(kscsConfiguration, protectionParameter, providers);
PasswordCredential passwordVredential = keyStoreCredentialStore.retrieve(WEBUSER_PASSWORD_ALIAS,
PasswordCredential.class,
KeyStoreCredentialStore.KEY_STORE_CREDENTIAL_STORE,
null,
protectionParameter);
return passwordVredential.getPassword();
}
With this code I can read the aliases from the credential store, but I'm nor able to retrieve the password. I just can't figure out how to put the proper parameters into the retrieve() function call.
Solution 2.
I tried to use the SeviceContainer, but the call CurrentServiceContainer.getServiceContainer() returns null.
public static String getClientSecret(String credentialStore, String secretAlias) { final ServiceName SERVICE_NAME_CRED_STORE = ServiceName.of("org", "wildfly", "security", "credential-store"); final ServiceName sn = ServiceName.of(SERVICE_NAME_CRED_STORE, credentialStore); final ServiceRegistry registry = CurrentServiceContainer.getServiceContainer(); final ServiceController<?> credStoreService = registry.getService(sn); final CredentialStore cs = (CredentialStore) credStoreService.getValue(); if (!cs.exists(secretAlias, PasswordCredential.class)) { throw new CredentialStoreException("Alias " + secretAlias + " not found in credential store."); } final Password password; try { password = cs.retrieve(secretAlias, PasswordCredential.class).getPassword(); } catch (CredentialStoreException e) { e.printStackTrace(); return null; } if (!(password instanceof ClearPassword)) { throw new ClassCastException("Password is not of type ClearPassword"); } return new String(((ClearPassword) password).getPassword()); }
How could I retrieve the password from that credential sore?