无法使用libsodium

时间:2019-02-08 07:08:16

标签: php encryption cryptography libsodium

我正在使用libsodium进行加密,我的问题是解密部分,它没有通过并显示错误。

  

致命错误:未捕获的SodiumException:操作限制必须大于   C:\ xampp \ htdocs \ encrypter \ decrypt.php:18中的堆栈跟踪:#0   C:\ xampp \ htdocs \ encrypter \ decrypt.php(18):sodium_crypto_pwhash()#1   {main}在第18行的C:\ xampp \ htdocs \ encrypter \ decrypt.php中抛出

我试图在加密代码中复制一些行,但是没有用。

我也收到警告。

但是我不知道这是否是原因。我也收到加密的邮件。

  

警告:unpack():64位格式代码不适用于32位   第11行的C:\ xampp \ htdocs \ encrypter \ decrypt.php中的PHP版本

     

警告:unpack():64位格式代码不适用于32位   第12行的C:\ xampp \ htdocs \ encrypter \ decrypt.php中的PHP版本

更新

  • 通过将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中使用的源代码。

1 个答案:

答案 0 :(得分:2)

该代码确实不是为32位版本的PHP设计的。

如果将std::distance更改为 Future getCarouselWidget() async { var firestore = Firestore.instance; QuerySnapshot qn = await firestore.collection("carousel").getDocuments(); return qn.documents; } Widget build(BuildContext context) { return Container( child: FutureBuilder( future: getCarouselWidget(), builder: (context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return new CircularProgressIndicator(); } else { if (snapshot.hasError) { return new Text("fetch error"); } else { return new Container( height: 250.0, child: new Carousel( boxFit: BoxFit.cover, images: [NetworkImage(snapshot.data[0].data["img_2"])], autoplay: false, dotSize: 4.0, indicatorBgPadding: 4.0, animationCurve: Curves.fastOutSlowIn, animationDuration: Duration(milliseconds: 1000), )); } } }), ); }' ,则需要:

  • 在调用P和调用V中都这样做
  • 将读取/写入的字节数从8更改为4。

但是最好的办法实际上是尝试理解代码的作用。

它在文件的开头存储内存限制和迭代次数,以便稍后在读取文件时可以恢复这些参数,而不必对其进行硬编码。

unpack()以固定的字节数编码值。 pack()则相反。 pack()将64位值编码为8个字节。 unpack()读取8个字节并将其转换为值。

如果您的环境不支持64位值,请打包/解压缩为4个字节,但是随后您需要写入4个字节(而不是8个),并且还要读取4个字节,而不是8个。