Question

I have found a nice basic cipher class which I am now using to convert all plain-text passwords in my MySQL Database. Currently the rows containing passwords are varchar(64) but I believe they should be converted to char(128). Can anyone confirm that 128 length will be long enough for the encrypted hash returned by this class?

I see it hashes the key with sha256 but uses MCRYPT_RIJNDAEL_128 so I am not sure if I need to make the length char(128) or char(256)

<?php

class Cipher
{

    private $securekey;
    private $iv_size;

    function __construct($textkey)
    {
        $this->iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
        $this->securekey = hash('sha256', $textkey, TRUE);
    }

    function encrypt($input)
    {
        $iv = mcrypt_create_iv($this->iv_size);
        return base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->securekey, $input, MCRYPT_MODE_CBC, $iv));
    }

    function decrypt($input)
    {
        $input = base64_decode($input);
        $iv = substr($input, 0, $this->iv_size);
        $cipher = substr($input, $this->iv_size);
        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->securekey, $cipher, MCRYPT_MODE_CBC, $iv));
    }

}

?>
Was it helpful?

Solution

Can anyone confirm that 128 length will be long enough for the encrypted hash returned by this class?

Maybe? Run some tests. Look at the documentation.

Currently the rows containing passwords are varchar(64) but I believe they should be converted to char(128).

Keep them as VARCHAR, change the length to 255. VARCHARS are stored in the backend as the string, plus one or two bytes to denote the length. One byte for 1 to 255, two bytes for 256-65535.

eg:

A VARCHAR(255) containing the word "butts" comprises 6 bytes of storage in the back end.

A CHAR(128) containing the word "butts" comprises 128 bytes of storage in the back end.

OTHER TIPS

As far as I can tell AES-256 and RIJNDAEL-128 are 256 bit long, so you probably are safe with char(32). (check Lessons learned implementing AES in PHP using Mcrypt )

Anyway you can always use VARCHAR(256) if you are not sure. It's dynamic allocation will keep you safe and the CHAR vs. VARCHAR performance won't affect you that much.

  • You don't need to encrypt a hashed password. Hashing is not reversible, so it's secure.

  • You should add a salt to the password before hashing it. Or else use bcrypt, which automatically salts.

  • The length of a SHA256 hash is always 256 bits, which can be stored in 64 characters or 32 binary bytes. See my answer to MySQL: what data type to use for hashed password field and what length?

  • Others have advised using VARCHAR(255) because that only stores the characters you need for a given string. This is true for storage in data rows and indexes, but when such strings are copied out of the MySQL storage engine and brought into MySQL's SQL result set, they are temporarily padded out to the full string length. So it's wasteful to use VARCHAR(255) as a de facto string column.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top