Search code examples
javasecurityhashmd5message-digest

Generating an MD5 Hash with a char[]


How would one go about converting a char[] password obtained using this method:

char[] password = passwordInputField.getPassword();

To an MD5 Hash? Normally I would use the method below, but getBytes is only compatible with Strings:

MessageDigest md = MessageDigest.getInstance("MD5");
md.update(password.getBytes());
String hashedPass = new BigInteger(1, md.digest()).toString(16);

Solution

  • NOTE: The MD5 Hashing Algorithm should never be used for password storage, as it's hashes are easily cracked. However, I will use it for simplicity.

    The quick/easy/UNSECURE fix would be to convert the char array to a string. However, this is unsecure because strings are immutable and can't be cleared from memory.

    String password = new String(passwordInputField.getPassword());
    
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(password.getBytes());
    String hashedPass = new BigInteger(1, md.digest()).toString(16);
    

    A more secure solution: convert the char[] to a byte[] and clear the arrays from memory afterward.

    private byte[] toBytes(char[] chars) {
        CharBuffer charBuffer = CharBuffer.wrap(chars);
        ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);
        byte[] bytes = Arrays.copyOfRange(byteBuffer.array(),
                byteBuffer.position(), byteBuffer.limit());
        Arrays.fill(charBuffer.array(), '\u0000'); // clear sensitive data
        Arrays.fill(byteBuffer.array(), (byte) 0); // clear sensitive data
        return bytes;
    }
    
    char[] passChars = passwordInputField.getPassword();
    byte[] passBytes = toBytes(passChars);
    
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(passBytes);
    String hashedPass = new BigInteger(1, md.digest()).toString(16);
    
    Arrays.fill(passChars, '\u0000'); // clear sensitive data
    Arrays.fill(passBytes, (byte) 0); // clear sensitive data
    

    EDIT:

    Updated answer with a more secure solution (credit to user2656928 for the idea).

    char[] to byte[] method credit to andreyne