Search code examples
phpencryptionmcrypt

Is the raw output returned by PHP's hashing functions the same as pack('H*')?


PHP's various hashing functions like md5(), sha1(), hash(), hash_pbkdf2() and hash_hmac() allow you to set $raw_output = false and get raw binary data.

I have put together a class that encrypts using mcrypt and hash_pbkdf2. When creating the key both of the following code work:

// Version 1
private function createKey($salt, $password) {
    // Hash the key
    $key = hash_pbkdf2('sha256', $password, $salt, 5000, 32, true);
    return $key;
}

// Version 2
private function createKey($salt, $password) {
    // Hash the key
    $key = hash_pbkdf2('sha256', $password, $salt, 5000);
    // Pack the key into a binary hex string
    $key = pack('H*', $key);
    return $key;
}

They both produce the same key size but are they both doing the same thing? Is either more secure than the other given that I'm using this for cryptography?


Solution

  • If you want to have raw binary result, you should go with hash_pbkdf2 with $raw_output = true. It will generate the bytes that you want without any encoding.

    hash_pbkdf2 internally uses bin2hex to then encode the binary string into hex. This is an additional operation. When you then use pack to decode the hex into the binary string, you have yet another unnecessary operation.

    Using hex output and decoding it back to binary does not improve your security. If anything, it might decrease it, because password hackers might not use these unnecessary steps.

    If you're concerned whether bin2hex actually reverses pack("H*"), you should use hex2bin as those are companion functions that are probably reversing each other.