使用PHP OpenSSL加密文件

时间:2013-06-20 21:51:26

标签: php openssl

通常,我使用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或其他人的“匿名”库,也不想使用命令行。

2 个答案:

答案 0 :(得分:1)

对于php来说,如果没有临时文件,就无法使用aes-256-ctr。

但是对于下一个chiper类型:

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对你有帮助吗?

答案 1 :(得分: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必须是唯一的且未知,但不需要是随机的。