WildFly: randomly salted passwords in Java EE application

前端 未结 1 1147
难免孤独
难免孤独 2021-02-06 16:57

What is the WildFly (8.2) way to work with randomly salted passwords stored in a database?

Is an implementation of org.jboss.crypto.digest.DigestCallback (i

1条回答
  •  花落未央
    2021-02-06 17:18

    It looks to me like the 'WildFly way' to deal with passwords is to do what most containers do and deliver a non-secure solution out-of-the-box. I don't know why, but every standard JDBC realm implementation I've seen so far just hashes the passwords without salt... Which is totally insecure.

    Open Source solution

    EDIT: I found an out-of-the box solution that works on WildFly. I ended up using it myself and it works well. I can recommend it:

    m9aertner/PBKDF2

    Here is how I configured it:

    First add a module to WildFly by creating a folder below modules/, like this:

    C:\WildFly\v8.2.0\modules\de\rtner\PBKDF2\main

    Place the PBKDF2-1.1.0.jar file in it along with a module.xml with these contents:

    
    
      
        
      
      
        
        
      
    `
    

    Then, add a realm configuration to standalone.xml:

    
      
        
    
        
          
            
              
              
              
              
              
            
          
        
    
        
      
    
    

    The SQL queries are the same as for the standard DatabaseLoginModule. The default hashing options need not be specified (as they are default) but you do need to be aware of them (and set them correctly) when creating new users in order to hash their password correctly with the same parameters.

    Example use

    Here is what I am doing in my code to create a new password hash (including salt) based on a given plaintext:

    public static String hash(String plainText, String storedPassword) {
        if (plainText == null) return null;
        SimplePBKDF2 crypto = new SimplePBKDF2();
        PBKDF2Parameters params = crypto.getParameters();
        params.setHashCharset("UTF-8");
        params.setHashAlgorithm("HmacSHA1");
        params.setIterationCount(1000);
        if (storedPassword != null) {
            new PBKDF2HexFormatter().fromString(params, storedPassword);
        }
        return crypto.deriveKeyFormatted(plainText);
    }
    

    When creating a new password, you would call this function passing null as the storedPassword:

    String password = hash('MySecretPassword', null);
    

    password would end up looking something like this:

    "192EAEB3B7AA40B1:1000:4C137AF7AD0F3999D18E2B9E6FB726D5C07DE7D5"
    

    When comparing passwords, you call the same function, passing the original password and then compare the results:

    String enteredPassword = hash(userInput, password);
    if (enteredPassword.equals(password)) {
        // Ok!
    }
    

    The reason you need to pass the original password is that the hashing parameters and salt are stored in the password hash, so the algorithm needs the stored password to get these parameters and use them for the new hash. However you don't usually need to compare passwords yourself as this is already done in the login module.

    Or, roll your own

    This blog post gives some explanation on how to roll your own Realm implementation that does add salt. He has source code on GitHub so maybe use that.

    It's for Glassfish, but I think it doesn't matter as far as the Realm implementation code goes.

    0 讨论(0)
提交回复
热议问题