Не могу расшифровать зашифрованный файл с помощью libsodium - PullRequest
0 голосов
/ 08 февраля 2019

Я работаю над шифрованием с использованием libsodium, моя проблема - это часть дешифрования, она не проходит и выдает ошибку.

Неустранимая ошибка: Uncaught SodiumException: предел операций должен быть больше 0 вC: \ xampp \ htdocs \ encrypter \ decrypt.php: 18 Трассировка стека: # 0 C: \ xampp \ htdocs \ encrypter \ decrypt.php (18): натрия_crypto_pwhash () # 1 {основной}, брошенный в C: \ xampp \htdocs \ encrypter \ decrypt.php в строке 18

Я попытался скопировать некоторые строки в коде шифрования, но не сработал.

Я также получил предупреждение.

Но я не знаю, в этом ли причина.Я также получаю это при шифровании.

Предупреждение: unpack (): 64-битные коды формата недоступны для 32-битных версий PHP в C: \ xampp \ htdocs \ encrypter \ decrypt.phpв строке 11

Предупреждение: unpack (): 64-битные коды формата недоступны для 32-битных версий PHP в C: \ xampp \ htdocs \ encrypter \ decrypt.php в строке 12

ОБНОВЛЕНИЕ

  • Предупреждение исправляется путем изменения кода пакета () с P на V.

  • При изменении кода $opslimit имеет значение больше 0.

DECRYPTION CODE

$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 .

1 Ответ

0 голосов
/ 08 февраля 2019

Код действительно не предназначен для 32-битных версий PHP.

Если вы измените P на V, вам необходимо:

  • Сделать это ввызовы unpack() и вызовы pack()
  • Измените число прочитанных / записанных байтов с 8 на 4.

Но на самом деле лучше всего попытатьсяпонять, что делает код.

Он хранит лимит памяти и итерации в начале файла, так что эти параметры могут быть восстановлены позже при чтении файла, без необходимости их жесткого кодирования.

pack() кодирует значение в фиксированном количестве байтов.unpack() делает наоборот.pack('P') кодирует 64-битное значение в 8 байтов.unpack('P') читает 8 байтов и преобразует их в значение.

Если ваша среда не поддерживает 64-битные значения, упакуйте / распакуйте в 4 байта, но затем вам нужно записать 4 байта, а не 8. Ичитать также 4 байта, а не 8.

...