在php中使用mcrypt进行密码加密

在php中使用mcrypt进行密码加密,php,encryption,passwords,mcrypt,Php,Encryption,Passwords,Mcrypt,我想知道我可以使用这个加密解密脚本进行密码加密并将其放入数据库吗? sql表密码列结构是什么(当前为passwordvarchar(32)NOTNULL)。 请注意,此脚本使用32字节十六进制密钥作为加密密钥 <?php define('ENCRYPTION_KEY', '32-byte hexadecimal encryption key'); function mc_encrypt($encrypt, $key) { $encrypt = serialize($encrypt)

我想知道我可以使用这个加密解密脚本进行密码加密并将其放入数据库吗? sql表密码列结构是什么(当前为
password
varchar(32)NOTNULL)。 请注意,此脚本使用32字节十六进制密钥作为加密密钥

<?php

define('ENCRYPTION_KEY', '32-byte hexadecimal encryption key');

function mc_encrypt($encrypt, $key)
{
  $encrypt = serialize($encrypt);
  $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_DEV_URANDOM);
  $key = pack('H*', $key);
  $mac = hash_hmac('sha256', $encrypt, substr(bin2hex($key), -32));
  $passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $encrypt.$mac, MCRYPT_MODE_CBC, $iv);
  $encoded = base64_encode($passcrypt).'|'.base64_encode($iv);
  return $encoded;
}

function mc_decrypt($decrypt, $key)
{
  $decrypt = explode('|', $decrypt);
  $decoded = base64_decode($decrypt[0]);
  $iv = base64_decode($decrypt[1]);
  if(strlen($iv)!==mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC)){ return false; }
  $key = pack('H*', $key);
  $decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $decoded, MCRYPT_MODE_CBC, $iv));
  $mac = substr($decrypted, -64);
  $decrypted = substr($decrypted, 0, -64);
  $calcmac = hash_hmac('sha256', $decrypted, substr(bin2hex($key), -32));
  if($calcmac!==$mac){ return false; }
  $decrypted = unserialize($decrypted);
  return $decrypted;
}
?>

除非严格要求(即处理旧协议),否则不应存储密码(加密或不加密)。而是使用基于PBKDF(如PBKDF2、bcrypt或scrypt)的密码哈希函数


请注意,加密不使用AES,而是使用块大小为256位的Rijndael。还要注意的是,密钥处理是次优的,很容易在密钥参数方面出错。否则代码乍一看就没问题。

注意:如果你只是想验证密码,你不应该存储密码,甚至不应该加密;例如,阅读。您将在哪里存储加密/解密密钥?其他注意事项:您使用的不是AES,而是块大小为256的Rijndael。否则,加密似乎可以,即使它使用MAC-then encrypt而不是encrypt-then-MAC。请注意,密钥处理非常奇怪,似乎可以给它一个48字节的密钥,让加密密钥具有前32个字节,HMAC密钥具有后16个字节。但是如果你给它中间的任何东西,键会重叠。请确保您了解密钥处理,否则以后可能无法解密。@owlstead。谢谢您的回答。您提供的链接非常有用。另外请注意,存在一个名为的网站。请注意,您应该始终尝试并包含一个语言标记。