无法解密密码

Dan*_*Dan 0 php encryption-symmetric

我最近决定对我的密码使用更安全的密码。调用mc_encrypt($encrypt)方法返回加密的密码后,我对密码进行加密没有问题 。

通过调用进行解密时mc_decrypt($decrypt),该方法返回false。如您在mc_decrypt($decrypt)方法中所见,底部附近有一个if语句。我无法通过if语句。有谁知道我可以改变以获得$calcmac!==$mac真实的回报?谢谢

<?php

    class Encrypt {
    public $encryptionKey = 'xxxxxxx';

    public function __construct() {
    define('ENCRYPTION_KEY', $this->encryptionKey);
    }

    // Encrypt Function
    public function mc_encrypt($encrypt){
        $encrypt = serialize($encrypt);
        $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_DEV_URANDOM);
        $key = pack('H*', $this->encryptionKey);
        $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;
    }

    // Decrypt Function
    public function mc_decrypt($decrypt){
        $decrypt = explode('|', $decrypt);
        $decoded = base64_decode($decrypt[0]);
        $iv = base64_decode($decrypt[1]);
        $key = pack('H*', $this->encryptionKey);
        $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;
    }

    }

    ?>
Run Code Online (Sandbox Code Playgroud)

Ste*_*eAp 5

抱歉,用服务器上存储的秘密加密密码并不安全:如果入侵者闯入您的代码库,则入侵者可以使用您的代码库和存储的密码(在代码或持久性存储中的某个位置)检索每个密码。

OWASP在线Web应用程序安全性项目)提供了充分准备的文档:密码存储备忘单身份验证备忘单PHP安全备忘单。看一看!

要走的路是撒盐

如何处理新创建的密码

  • 如果您创建新密码,请hash = HashFunction( password, salt )使用随机盐进行计算
  • 将哈希和盐值与用户ID一起保存在数据库中

如何验证密码

  • 在您的数据库中找到用户ID的记录
  • 从记录中检索哈希和盐
  • 根据用户输入的密码登录,计算 hash = HashFunction( enteredPassword, salt )
  • 最后,验证从存储中检索的哈希值是否与计算得出的哈希值相同。

为什么要使用哈希运算?

哈希运算是所谓的陷门函数:尽管您可以轻松地计算函数,但很难计算逆函数结论:从密码计算密码哈希很容易,但是从密码哈希计算密码很困难。

PHP的哈希函数

如今,PHP的PBKDF2是密码哈希的首选[PBKDF2上的维基百科]

如果您的PHP安装太旧,即使使用盐腌的哈希md5()也比使用两次加密的密码更好。但是只有在绝对没有其他可用的情况下!

PBKDF2使用示例

function getHashAndSaltFromString( $password ) {

   // choose a sufficiently long number of iterations 
   // ... to make the operation COSTLY
   $iterations = 1000;

   // Generate a random IV using mcrypt_create_iv(),
   // openssl_random_pseudo_bytes() or another suitable source of randomness
   $salt = mcrypt_create_iv(16, MCRYPT_DEV_RANDOM);

   $hash = hash_pbkdf2("sha256", $password, $salt, $iterations, 20);

   return array( $hash, $salt );

}
Run Code Online (Sandbox Code Playgroud)

哈希使用的美丽副作用

许多网站确实将密码的长度限制为一定的长度-很有可能是由于基础持久性存储的长度[=数据库表中字段的长度]。

如果您使用基于哈希的密码存储技术,则您的用户可能会使用任意长度的密码

由于哈希是恒定长度的,并且您仅保留密码和盐,因此长度限制是多余的。在您的网络应用中支持长密码!

在极端情况下,您甚至可以允许用户上传文件(例如,其家庭照片)作为凭据[= password]。

有关PHP MCRYPT函数中随机源的补充说明

请注意,PHP确实提供了两种随机性MCRYPT_DEV_RANDOM和来源MCRYPT_DEV_URANDOM

  • MCRYPT_DEV_RANDOM 从中获得随机性 /dev/random
  • MCRYPT_DEV_URANDOM 从中获得随机性 /dev/urandom

/dev/urandom立即提供随机数据,并且在您每次查询时都会无阻塞,/dev/random可能会阻塞(需要一些时间才能返回)。

因此,一见倾心/dev/urandomMCRYPT_DEV_URANDOM可能更适合于随机数生成。其实不是!

/dev/random可能会阻塞请求,直到某个时间点为止,此时已收集到足够多的。因此,/dev/randomMCRYPT_DEV_RANDOM有效地收集随机性。

如果您需要进行强大的加密操作,请使用MCRYPT_DEV_RANDOM/dev/random