2

通常,我openssl_encrypt在 PHP 中使用 AES 加密简单的字符串,效果很好。

现在我需要使用 AES-256-CTR 模式加密文件,但唯一的方法是对file_get_contents文件的全部内容进行加密,然后将其发送到openssl_encrypt函数以加密实际文件数据。问题是这种方法非常“差”,因为内存严重浪费。

1) 有没有办法使用 PHP OpenSSL 处理分块数据?

例如:

<?php
// ...
$f = fopen('large.iso','r');
  while(feof($f)){
    $chunk = fread($f,16);
       $cipher = openssl_encrypt(...$chunk...);
    // ... code ...
   }
    // ... more code ...
?>

2)openssl_encrypt官方文档尚未发布。有人可以澄清用于 AES-CTR 模式的函数参数的含义吗?计数器是否自动处理?是否有必要对函数返回的数据进行手动异或?

注意:这是一个专业项目,所以我不想使用phpseclib或其他人的“匿名”库,也不想使用命令行。

4

2 回答 2

1

1)它应该是这样的:

function strtohex($x) {
    $s = '';
    foreach (str_split($x) as $c){
        $s.=sprintf("%02X", ord($c));
    }
    return($s);
}

$method = "aes-256-ctr"; //aes-256-cbc
echo "Selected method: ".$method."<br /><br />";
$textToEncrypt = "My chunk of data";
$iv = "1234567890123456";
$pass = 'some_pass';
$dec_iv = strtohex($iv);
$key = strtohex($pass);
$enc_data = openssl_encrypt($textToEncrypt, $method, $pass, true, $iv);
echo "Encrypted message (openssl): ".$enc_data."<br />";
$dec_data = openssl_decrypt($enc_data, $method, $pass, OPENSSL_RAW_DATA, $iv);
echo "Decrypted message (openssl): ".$dec_data."<br />";

对于 CTR $iv 对于每个块应该是唯一的,否则您的数据可能会被破坏。

2)我只知道 CBC 和 CTR 之间的区别:

对于 CBC,IV 必须是随机的,但不是唯一的。也不得为人所知。

对于 CTR,IV 必须是唯一且未知的,但不需要是随机的。

于 2013-06-20T23:59:23.593 回答
1

看起来对于 php,没有临时文件是不可能使用 aes-256-ctr 的。

但对于下一个芯片类型:

OPENSSL_CIPHER_RC2_40 
OPENSSL_CIPHER_RC2_128 
OPENSSL_CIPHER_RC2_64  
OPENSSL_CIPHER_DES 
OPENSSL_CIPHER_3DES 
OPENSSL_CIPHER_AES_128_CBC 
OPENSSL_CIPHER_AES_192_CBC  
OPENSSL_CIPHER_AES_256_CBC 

您可以即时使用生成密钥:

$res = openssl_pkey_new('chiper args here');
openssl_pkey_export($res, $private_key);

$public_key = openssl_pkey_get_details($res);
$public_key = $public_key["key"];

然后加密:

$crypted_text = openssl_get_privatekey($private_key,'your data'); 

并解密:

openssl_public_decrypt($crypted_text,$decrypted_text,$public_key);

因此,如果您不想使用文件,可能切换到 OPENSSL_CIPHER_AES_256_CBC 会对您有所帮助吗?

于 2013-06-20T22:29:37.577 回答