I tried to rebuild the the encryption flow explained here
Encryption
$password = 'pass123456'; //user password
$message = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.';
$Ku = openssl_random_pseudo_bytes(256 / 8); //user-specific symmetric key
$Ru = openssl_random_pseudo_bytes(256 / 8); //recovery code
$Su = openssl_random_pseudo_bytes(256 / 8); //user salt ###STORED ON SERVER###
$hash = hash_pbkdf2('sha256', $password, $Su, 5000, 256 / 8, true);
$split = str_split($hash, 16);
$Vu = $split[0]; //password verification token ###STORED ON SERVER###
$Ek = $split[1]; //key to encrypt Ku
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$Eu = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $Ek, $Ku, MCRYPT_MODE_CBC, $iv); ###STORED ON SERVER###
$Fu = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $Ru, $Ku, MCRYPT_MODE_CBC, $iv); ###STORED ON SERVER###
$encryptedMessage = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $Ku, $message, MCRYPT_MODE_CBC, $iv);
Decryption
$hash = hash_pbkdf2('sha256', ###ENTERED PASSWORD###, ###STORED Su###, 5000, 256 / 8, true);
$split = str_split($hash, 16);
$Vu = $split[0];
$Ek = $split[1];
if($Vu != ###STORED Vu###) {
=> wrong password
} else {
=> correct password
}
$Ku = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $EK, ###STORED Eu###, MCRYPT_MODE_CBC, ###STORED iv###);
$message = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $Ku, $encryptedMessage, MCRYPT_MODE_CBC, ###STORED iv###);
If I have lost my password I can recover "Ku":
$Ku = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, ###REVOVERY KEY###, ###STORED Fu###, MCRYPT_MODE_CBC, ###STORED iv###);
Is the code above secure? Is openssl_random_pseudo_bytes
random enough or is there a better possibility i.e. using mouse movement to generate a initialization number?
How should the "initialization vector" for mcrypt be handled? Is this correct?