在PHP和命令行之间复制openssl加密/解密大文件?

replicate openssl encrypt/decrypt between PHP and Command Line for large files?

提问人:Bilal H 提问时间:11/14/2023 更新时间:11/14/2023 访问量:69

问:

我正在尝试创建一个PHP方法来复制OpenSSL命令行函数,这样我就可以使用命令行进行加密,然后使用PHP进行解密,或者相反,通过使用PHP加密,然后使用命令行进行解密。

我创建了这个PHP方法来加密文件:

$salt= random_bytes(8);
$saltPrefix = "Salted__" . $salt;
$keyIV= EVP_BytesToKey($salt, file_get_contents('my.key'));
$key = substr($keyIV, 0, 32);
$original = file_get_contents('confidential.txt');
$encrypted = openssl_encrypt($original, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
file_put_contents('php-encrypted.bin', $saltPrefix . $encrypted);

然后在运行此方法后,我可以使用以下命令行对其进行解密:

openssl  enc -p -d -aes-256-cbc -in php-encrypted.bin -out decrypted.txt -pass file:my.key

但是当要加密的文件很大时会出现问题,所以我尝试更新上面的PHP方法,以免出现内存限制问题:

$FILE_ENCRYPTION_BLOCKS = 64;
if ($fpOut = fopen('php-encrypted.bin', 'w')) {
    fwrite($fpOut, $saltPrefix);
    if ($fpIn = fopen('confidential.txt', 'rb')) {
        while (!feof($fpIn)) {
            $plaintext = fread($fpIn, 16 * $FILE_ENCRYPTION_BLOCKS);
            $encrypted = openssl_encrypt($plaintext, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
            fwrite($fpOut, $encrypted);
        }
        fclose($fpIn);
    }
    fclose($fpOut);
}

但是当我尝试像以前一样使用命令行解密生成的文件时,它不起作用。我需要更新上述方法以遵循内存性能问题,但希望能够像原始方法一样使用命令行对其进行加密。

php 加密 openssl 大文件 php-openssl

评论

2赞 Topaco 11/14/2023
如果要以块(对应于一个块或 16 个字节的整数倍)连续执行 AES/CBC 加密,对于明文块的加密,必须将前一个密文块的最后一个块用作 IV(对于第一个明文块,应用实际的 IV),另请参阅 CBC 流程图.此外,必须为所有块禁用填充(最后一个块除外)。类似的情况也适用于解密。
0赞 Bilal H 11/14/2023
我尝试用这个替换,在循环中,最后,我添加了,但解密命令行仍然不起作用。OPENSSL_RAW_DATA $options = feof($fpIn) ? OPENSSL_RAW_DATA : OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING; $iv = substr($encrypted, 0, 16);
0赞 Topaco 11/14/2023
您必须将前一个密文块的最后一个块用作 IV,而不是第一个块:$iv = substr($encrypted, -16);
0赞 Bilal H 11/15/2023
啊,对不起,我认为第一个块,非常感谢@Topaco它现在正在工作。
0赞 Bilal H 11/15/2023
如果我想使用 CTR,openssl_encrypt加密块需要做哪些更改,我可以将计数器发送到哪里以及如何获取它?

答: 暂无答案