通常,我在PHP中使用openssl_encrypt
用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
或其他人的"匿名"库,也不想使用命令行。
对于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会对你有所帮助吗?
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必须是唯一的且未知的,但不需要是随机的。