openssl_decrypt(): ошибка установки тега для дешифрования шифра AEAD

#php #laravel #encryption #php-openssl

#php #laravel #шифрование #php-openssl

Вопрос:

надеюсь, у вас все отлично.

Я работаю над шифрованием / дешифрованием с использованием расширения openssl. Когда я кодирую, как показано ниже, он работает нормально, даже если я не использую bin2hex(). Пожалуйста, обратите внимание, что $tag имеет статическое значение для каждого пользователя, оно никогда не изменится, в отличие от $ iv и $ key.

 $plaintext = 'password';
$cipher = "aes-128-gcm";
$tag = 'tqjFo ChP8UB2gHkG9F5Vw==';
echo '<pre>';       

    $ivlen = openssl_cipher_iv_length($cipher);
    $key = openssl_random_pseudo_bytes($ivlen);
    $iv = openssl_random_pseudo_bytes($ivlen);
    
    $iv = bin2hex($iv);
    $key = bin2hex($key);

    $encrypted = bin2hex(openssl_encrypt($plaintext, $cipher, $key, $options=0, $iv,$tag));
    $decrypted = openssl_decrypt(hex2bin(($encrypted)), $cipher, $key, $options=0, $iv,$tag);
    echo 'key='.$key. "n";
    echo 'iv='.$iv. "n";
    echo 'plaintext='.$plaintext. "n";
    echo 'encrypted to: '.$encrypted. "n";
    echo 'decrypted to: '.$decrypted. "nn";


echo '</pre>';
  

Проблема в том, что мне приходится хранить $ iv, $ key и
$encrypted
в базе данных (MySQL) и использовать их для последующего дешифрования.

Сначала позвольте мне показать вам, как я это делаю

База данных (я не уверен в типе поля, оно должно быть строковым, двоичным и т. Д.)

введите описание изображения здесь

Эта функция шифрует пароль и сохраняет $ iv, $ key и $ EncryptedData в базе данных

 public function createOpenSSL(Request $req){
    $plaintext = $req->password;
    $cipher = "aes-128-gcm";
    $tag = "tqjFo ChP8UB2gHkG9F5Vw==";
    $ivlen = openssl_cipher_iv_length($cipher);
    $key = openssl_random_pseudo_bytes($ivlen);
    $iv = openssl_random_pseudo_bytes($ivlen);
    $iv = bin2hex($iv);
    $key = bin2hex($key);
    $encrypted = openssl_encrypt($plaintext, $cipher, $key, $options=0, $iv,$tag);
    $user = new openssl();
    $user->password = $encrypted;
    $user->ukey = $key;
    $user->iv =$iv;
    $user->save();

}
  

Эта функция найдет пользователя, соответствующего «id», и расшифрует
пароль (но, к сожалению, он не работает)

 public function showOpenSSL(Request $req){
    $user = openssl::findorFail($req->id);
    $cipher = "aes-128-gcm";
    $tag = "tqjFo ChP8UB2gHkG9F5Vw==";
    $key = hex2bin($user->ukey);
    $iv = hex2bin($user->iv);
    $encrypted = $req->password;
    $decrypted = openssl_decrypt($encrypted, $cipher, $key, $options=0,$iv,$tag);  
}
  

При выполнении вышеуказанной функции возникает ошибка «openssl_decrypt (): ошибка установки тега для дешифрования шифра AEAD». Я старался изо всех сил в течение последних 2 дней, но ничего не мог найти. Пожалуйста, скажите мне, где я делаю неправильно. Пожалуйста, также укажите мне тип поля базы данных, который лучше всего подходит для хранения $ iv, $ key и $ encrypted.

Комментарии:

1. Тег AEAD — это не то, что вы устанавливаете, он вычисляется в процессе шифрования и является более или менее контрольной суммой, созданной самим алгоритмом. Он будет отличаться для каждой операции шифрования. В принципе, вам также нужно сохранить тег. Большинство схем просто упаковывают IV, tag и зашифрованный текст в одну строку, поскольку все они всегда будут уникальными.

2. crypto.stackexchange.com/questions/67107/…

3. @Sammitch означает, что ТЕГ будет создан openssl_encryption()??

4. ДА. Он передается по ссылке в openssl_encrypt() , и в него записывается тег. Попробуйте проверить значение до и после операции.

5. Кроме того, если вы храните ключ шифрования рядом с зашифрованным текстом в БД, вы также можете хранить его в виде открытого текста. Безопасное хеширование ваших паролей намного проще.