Securing passwords is a common task for developers. Wildfly offers credential vaults for this task and manages to automatically use the secured passwords for datasources or active directory credentials. If you need to access a vault from java you need to read the SecurityVault with the help of the picketbox security classes of the Wildfly application server.

The steps to configure a Wildfly (and JBoss) security vault are explained on the JBoss website: https://developer.jboss.org/wiki/JBossAS7SecuringPasswords
If you have configured an attribute called password in a vault block called myDataSource you will have a string like ${VAULT::myDataSource::password::1} in your Wildfly configuration or in a properties file. If your task is to access such a secured password and use it in java code you need to read the secured information from the configured security vault.

The Wildfly security library has to be added to your project. The maven part for this is

<dependency>
   <groupId>org.picketbox</groupId>
   <artifactId>picketbox</artifactId>
   <version>your version</version>
   <scope>provided</scope>
</dependency>

After you have configured your project set-up to use the Wildfly security classes, you just need some lines of code to access the vault.

import java.nio.charset.StandardCharsets;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.jboss.security.vault.SecurityVault;
import org.jboss.security.vault.SecurityVaultFactory;

public class VaultReader {
    private static final Pattern VAULT_PATTERN = Pattern.compile("VAULT::.*::.*::.*");
    
    private VaultReader() {}
    
    public static boolean isVaultFormat(String str) {
        return str != null && VAULT_PATTERN.matcher(str).matches();
    }
    
    public static String decryptValue(String encryptedValue) throws SecurityException {
        String value = null;
        
        if (!isVaultFormat(encryptedValue)) {
            throw new SecurityException("Password is not in vault format.");
        }
        
        String [] tokens = tokens(encryptedValue);
        String vaultBlock = tokens[1];
        String attributeName = tokens[2];
        byte[] sharedKey = null;
        if (tokens.length > 3) {
            sharedKey = tokens[3].getBytes(StandardCharsets.UTF_8);
        }
        try {
            SecurityVault vault = SecurityVaultFactory.get();
            boolean exists = vault.exists(vaultBlock, attributeName);
            if (exists) {
                char [] pass = vault.retrieve(vaultBlock, attributeName, sharedKey);
                value = String.valueOf(pass);
            } else {
                throw new SecurityException(
                        String.format("Attribute %s does not exist in vaultblock %s", 
                                attributeName, vaultBlock));
            }
        } catch (Exception ex) {
            Logger.getLogger(VaultReader.class.getName()).log(Level.WARNING, null, ex);
        }
        return value;
    }

     private static String[] tokens(String vaultString) { 
         StringTokenizer tokenizer = new StringTokenizer(vaultString, "::"); 
         int length = tokenizer.countTokens(); 
         String[] tokens = new String[length]; 
         int index = 0; 
         while (tokenizer.hasMoreTokens()) { 
             tokens[index++] = tokenizer.nextToken(); 
         } 
         return tokens; 
     } 
}

 

The VaultReader class has just two public methods

  • boolean isVaultFormat(String password) : to check if the password is a secured vault attribute
  • String decryptValue(String password) throws SecurityException : to decrypt the password from the vault

The last step is to call these methods where you need it like

if (VaultReader.isVaultFormat(password)) {
  password = VaultReader.decryptValue (password);
}

That’s it, not much code isn’t it? One last thing… if you are working on a Wildfly module, you also have to configure the picketbox classes in the dependencies section of your module.xml file: <module name=”org.picketbox” /> Otherwise you will get ClassNotFoundExceptions.

 

By Meik Kaufmann

I am a certified oracle enterprise architect and like to share my knowledge and experience that I gain in the projects I am working on.

Leave a Reply

Your email address will not be published. Required fields are marked *