0

I have created a utility class for hashing and salting passwords. Then I store the user's password in a SQL database in the user table. I want to use EL to pull the password from the database, decrypt it and display it in a JSP. How do I decrypt the password that I retrieve back from the database? Here is the utility class:

public class PasswordUtil {

/*  This code uses SHA-256. If this algorithm isn't available to you,
    you can try a weaker level of encryption such as SHA-128.
*/    
public static String hashPassword(String password)
        throws NoSuchAlgorithmException {        
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.reset();
    md.update(password.getBytes());
    byte[] mdArray = md.digest();
    StringBuilder sb = new StringBuilder(mdArray.length * 2);
    for (byte b : mdArray) {
        int v = b & 0xff;
        if (v < 16) {
            sb.append('0');
        }
        sb.append(Integer.toHexString(v));
    }        
    return sb.toString();        
}

public static String getSalt() {
    Random r = new SecureRandom();
    byte[] saltBytes = new byte[32];
    r.nextBytes(saltBytes);
    return Base64.getEncoder().encodeToString(saltBytes);
}

public static String hashAndSaltPassword(String password)
        throws NoSuchAlgorithmException {
    String salt = getSalt();
    return hashPassword(password + salt);
}

public static void checkPasswordStrength(String password) throws Exception {
    if (password == null || password.trim().isEmpty()) {
        throw new Exception("Password cannot be empty.");
    } else if (password.length() < 8) {
        throw new Exception("Password is to short. " +
                "Must be at least 8 characters long.");
    }
}

public static boolean validatePassword(String password) {
    try {
        checkPasswordStrength(password);
    } catch (Exception e) {
        System.out.println(e.getMessage());
        return false;
    }
    return true;
}

}

Here is the JSP (just the table from the JSP for brevity) I want to display the decrypted password on:

     <table> 
            <tr>
                <td class="alignRight">First Name:</td>
                <td>${user.firstName}</td>
            </tr>
            <tr>
                <td class="alignRight">Last Name:</td>
                <td>${user.lastName}</td>
            </tr>
            <tr>
                <td class="alignRight">Phone Number:</td>
                <td>${user.phone}</td>
            </tr>
            <tr>
                <td class="alignRight">Address:</td>
                <td>${user.address}</td>
            </tr>
            <tr>
                <td class="alignRight">City:</td>
                <td>${user.city}</td>
            </tr>
            <tr>
                <td class="alignRight">State:</td>
                <td>${user.state}</td>
            </tr>
            <tr>
                <td class="alignRight">Zipcode:</td>
                <td>${user.zip}</td>
            </tr>
            <tr>
                <td class="alignRight">Email:</td>
                <td>${user.email}</td>
            </tr>
            <tr>
                <td class="alignRight">Your user name is:</td>
                <td>${user.userName}</td>
            </tr>
            <tr>
                <td class="alignRight">Temporary password:</td>
                <td>${user.password}</td>
            </tr>
        </table>
  • 6
    *I want to use EL to pull the password from the database, decrypt it and display it in a JSP.* That seems like a **really *bad*** idea. – Elliott Frisch May 03 '17 at 01:42
  • 3
    In all honesty, it is far better (more secure) **not** to decrypt a password but instead compare one encryption with another encryption held in database for a match. – DevilsHnd - 退職した May 03 '17 at 02:02
  • The idea is to assign the new user account a temporary password with the value "welcome1", decrypt it, and store it in a database. However when I display the new account information on the success.jsp page I want the user to see the temporary password unhashed. Normally, I wouldn't hash a temporary password upon the creation of an account but I have been asked to for a school assignment. I have not been asked to unhash it but I would like to know how you would do it if you needed to –  May 03 '17 at 02:04
  • 2
    You don't have to unhash the password to accomplish that objective. You only need to display the original password before it was hashed. – user207421 May 03 '17 at 03:41
  • 3
    **Do not encrypt passwords**, when the attacker gets the DB he will also get the encryption key. Just using a hash function is not sufficient and just adding a salt does little to improve the security. Iterate over an HMAC with a random salt for about a 100ms duration and save the salt with the hash. Use a function such as `password_hash`, `PBKDF2`, `Bcrypt` or similar functions. The point is to make the attacker spend a lot of time finding passwords by brute force. – zaph May 03 '17 at 04:39
  • 1
    *I have not been asked to unhash it but I would like to know how you would do it if you needed to* The whole purpose of hashing is to prevent people from doing exactly that. [hashing != encryption](http://stackoverflow.com/questions/4948322/fundamental-difference-between-hashing-and-encryption-algorithms). – Leigh May 03 '17 at 19:08

2 Answers2

1

You can't.

As I see it, you're using the one-way hash function SHA-256. The idea of a one-way hash function is that it only goes one way; you can't undo the hash.

You'll have to look at a "two-way hash function" (encryption/decryption), if you want to be able to revert your "digested" password stored in the DB. As Elliott Frisch says, it sounds like a really bad idea to me, though.

Kristin
  • 1,336
  • 7
  • 23
0

Being unable to do this is the entire point of hashing passwords. (Note that you're not storing the users' passwords; you're storing the hashes.)

But if you're dead-set on it, you could try creating your own rainbow tables using your salt.

  • Of course just hashing with a salt for passwords is not secure and should not be done. Also since the salt is random it is not possible to create a rainbow table or more specifically a rainbow table would be required for each salt and each rainbow table would have to have 2^256 entries each entry being 40 or so bytes…wow is that large. – zaph May 04 '17 at 19:32