更快运行openssl加密功能

时间:2018-07-23 12:15:01

标签: php encryption openssl php-7.2

这是与here发布的安全性相关的问题。

我在当前的PHP 7.0设置中使用的this正常工作。但是由于mcrypt从7.2开始已被openssl取代,因此我正在使用内置的here来更新加密和解密功能。​​

但这是因为该网页上有25个项目,因此执行时间很长,最终用户无法接受。

<?php
define("ENCRYPTION_KEY", "!@#$%^&*");

$StartTime = microtime(TRUE);

$e = [];
for ($i = 0; $i < 25; $i++)
{
    $e[] = encrypt($i, ENCRYPTION_KEY);
}

echo number_format(microtime(TRUE) - $StartTime, 3)." seconds\n";

# https://stackoverflow.com/a/50373095/126833
function sign($message, $key) {
    return hash_hmac('sha256', $message, $key) . $message;
}

function verify($bundle, $key) {
    return hash_equals(
      hash_hmac('sha256', mb_substr($bundle, 64, null, '8bit'), $key),
      mb_substr($bundle, 0, 64, '8bit')
    );
}

function getKey($password, $keysize = 16) {
    return hash_pbkdf2('sha256',$password,'some_token',100000,$keysize,true);
}

function encrypt($message, $password) {
    $iv = random_bytes(16);
    $key = getKey($password);
    $result = sign(openssl_encrypt($message,'aes-256-ctr',$key,OPENSSL_RAW_DATA,$iv), $key);
    return bin2hex($iv).bin2hex($result);
}

function decrypt($hash, $password) {
    $iv = hex2bin(substr($hash, 0, 32));
    $data = hex2bin(substr($hash, 32));
    $key = getKey($password);
    if (!verify($data, $key)) {
      return null;
    }
    return openssl_decrypt(mb_substr($data, 64, null, '8bit'),'aes-256-ctr',$key,OPENSSL_RAW_DATA,$iv);
}
?>

$ php encrypt-decrypt.php 
6.288 seconds

有什么方法可以快速执行此操作? (不到一秒钟的时间进行25次迭代)

1 个答案:

答案 0 :(得分:3)

PBKDF2的迭代次数称为工作因子。如果迭代次数很高,那么工作因子(PBKDF2需要执行的工作量)也就很高。请注意,迭代次数是线性且要执行的工作量很大,计算机以指数形式更快(接近)

请注意,PBKDF2实现可以在硬件和软件中加快。因此,请注意,攻击者将能够更快地执行它们。 100,000美元实际上是建议金额。


您的实现正确地调用了PBKDF2一小部分字节(小于哈希值的输出。如果不这样做,则PBKDF2基本上被调用了两次,而攻击者可能只调用一次来验证密码猜测。请注意,不要更改代码来要求输入两个密钥,这只会减慢服务器速度。

但是,您在$key = getKey($password);函数中调用了encrypt 。这意味着将为每个呼叫派生密钥。这当然不是很聪明:您应该缓存密钥,直到不再需要它为止,然后直接销毁它。无需导出密钥25次。只是降低迭代次数是一种临时解决方案,可以将大量优势移交给攻击者。