无法使用libsodium解密加密文件
Can't decrypt encrypted file using libsodium
我正在使用 libsodium 进行加密我的问题是解密部分,它没有通过并显示错误。
Fatal error: Uncaught SodiumException: ops limit must be greater than
0 in C:\xampp\htdocs\encrypter\decrypt.php:18 Stack trace: #0
C:\xampp\htdocs\encrypter\decrypt.php(18): sodium_crypto_pwhash() #1
{main} thrown in C:\xampp\htdocs\encrypter\decrypt.php on line 18
我尝试复制加密代码中的一些行,但没有成功。
我也收到警告。
但我不知道是不是这个原因。我在加密时也收到了这个。
Warning: unpack(): 64-bit format codes are not available for 32-bit
versions of PHP in C:\xampp\htdocs\encrypter\decrypt.php on line 11
Warning: unpack(): 64-bit format codes are not available for 32-bit
versions of PHP in C:\xampp\htdocs\encrypter\decrypt.php on line 12
更新
通过将 pack() 代码从 P
更改为 V
来修复警告。
更改代码后,$opslimit
的值大于 0。
解密代码
$password = 'password';
$encrypted_file = 'tmp/inc.php';
$decrypted_file = 'tmp/inc.dec';
$fd_in = fopen($encrypted_file, 'rb');
$fd_out = fopen($decrypted_file, 'wb');
$alg = unpack('C', fread($fd_in, 1))[1];
$opslimit = unpack('V', fread($fd_in, 8))[1];
$memlimit = unpack('V', fread($fd_in, 8))[1];
$salt = fread($fd_in, SODIUM_CRYPTO_PWHASH_SALTBYTES);
$header = fread($fd_in, SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES);
$secret_key = sodium_crypto_pwhash(SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES,
$password, $salt, $opslimit, $memlimit, $alg);
$stream = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $secret_key);
do {
$chunk = fread($fd_in, $chunk_size + SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES);
$res = sodium_crypto_secretstream_xchacha20poly1305_pull($stream, $chunk);
if ($res === FALSE) {
break;
}
list($decrypted_chunk, $tag) = $res;
fwrite($fd_out, $decrypted_chunk);
} while (!feof($fd_in) && $tag !== SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL);
$ok = feof($fd_in);
fclose($fd_out);
fclose($fd_in);
if (!$ok) {
die('Invalid/corrupted input');
}
这是我使用的来自 libsodium example.
的源代码
该代码确实不是为 PHP 的 32 位版本设计的。
如果将 P
更改为 V
,您需要:
- 在调用
unpack()
和调用 pack()
时都这样做
- 将字节数 read/written 从 8 更改为 4。
但最好的办法实际上是尝试理解代码的作用。
它将内存限制和迭代存储在文件的开头,以便以后读取文件时可以恢复这些参数,而不必对它们进行硬编码。
pack()
以固定字节数对值进行编码。 unpack()
则相反。
pack('P')
将 64 位值编码为 8 个字节。 unpack('P')
读取 8 个字节并将其转换为一个值。
如果您的环境不支持 64 位值,pack/unpack 到 4 个字节,但是您需要写入 4 个字节,而不是 8 个字节。同时读取 4 个字节,而不是 8 个字节。
我正在使用 libsodium 进行加密我的问题是解密部分,它没有通过并显示错误。
Fatal error: Uncaught SodiumException: ops limit must be greater than 0 in C:\xampp\htdocs\encrypter\decrypt.php:18 Stack trace: #0 C:\xampp\htdocs\encrypter\decrypt.php(18): sodium_crypto_pwhash() #1 {main} thrown in C:\xampp\htdocs\encrypter\decrypt.php on line 18
我尝试复制加密代码中的一些行,但没有成功。
我也收到警告。
但我不知道是不是这个原因。我在加密时也收到了这个。
Warning: unpack(): 64-bit format codes are not available for 32-bit versions of PHP in C:\xampp\htdocs\encrypter\decrypt.php on line 11
Warning: unpack(): 64-bit format codes are not available for 32-bit versions of PHP in C:\xampp\htdocs\encrypter\decrypt.php on line 12
更新
通过将 pack() 代码从
P
更改为V
来修复警告。更改代码后,
$opslimit
的值大于 0。
解密代码
$password = 'password';
$encrypted_file = 'tmp/inc.php';
$decrypted_file = 'tmp/inc.dec';
$fd_in = fopen($encrypted_file, 'rb');
$fd_out = fopen($decrypted_file, 'wb');
$alg = unpack('C', fread($fd_in, 1))[1];
$opslimit = unpack('V', fread($fd_in, 8))[1];
$memlimit = unpack('V', fread($fd_in, 8))[1];
$salt = fread($fd_in, SODIUM_CRYPTO_PWHASH_SALTBYTES);
$header = fread($fd_in, SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES);
$secret_key = sodium_crypto_pwhash(SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES,
$password, $salt, $opslimit, $memlimit, $alg);
$stream = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $secret_key);
do {
$chunk = fread($fd_in, $chunk_size + SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES);
$res = sodium_crypto_secretstream_xchacha20poly1305_pull($stream, $chunk);
if ($res === FALSE) {
break;
}
list($decrypted_chunk, $tag) = $res;
fwrite($fd_out, $decrypted_chunk);
} while (!feof($fd_in) && $tag !== SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL);
$ok = feof($fd_in);
fclose($fd_out);
fclose($fd_in);
if (!$ok) {
die('Invalid/corrupted input');
}
这是我使用的来自 libsodium example.
的源代码该代码确实不是为 PHP 的 32 位版本设计的。
如果将 P
更改为 V
,您需要:
- 在调用
unpack()
和调用pack()
时都这样做
- 将字节数 read/written 从 8 更改为 4。
但最好的办法实际上是尝试理解代码的作用。
它将内存限制和迭代存储在文件的开头,以便以后读取文件时可以恢复这些参数,而不必对它们进行硬编码。
pack()
以固定字节数对值进行编码。 unpack()
则相反。
pack('P')
将 64 位值编码为 8 个字节。 unpack('P')
读取 8 个字节并将其转换为一个值。
如果您的环境不支持 64 位值,pack/unpack 到 4 个字节,但是您需要写入 4 个字节,而不是 8 个字节。同时读取 4 个字节,而不是 8 个字节。