PHP использует пароль и соль для получения IV и Key альтернативы C # Rfc2898DeriveBytes (AES256)

Я хочу восстановить свой IV и Ключ от пароля и соли, которую я сохранил.
В моей программе на C # я делаю это следующим образом:

//passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);

Код для этого — PHP, возвращающий другой IV и ключ:

<?php
include("enctest_inc.php");

$password = "mypassword";
$salt = "mysalthereitis";

$hasher = "SHA256";
$iterations = 1000;
$keysize = 256;
$ivsize = 128;

$out = pbkdf2($hasher, $password, base64_decode($salt), $iterations, ($keysize+$ivsize)/8, true);

// split key and IV
$key = substr($out, 0, $keysize/8);
$iv = substr($out, $ivsize/8);

// print for demonstration purposes
echo base64_encode($key);
echo "<br>";
echo base64_encode($iv);
echo '<br>';
echo '<br>';

echo 'KEY : LNY893Wa00onNQh4ignFdjaVkg6GdxomMZoR/axB+Mw='; //KEY FROM SSH PROGRAM WHICH IS THE RIGHT RETURN;
echo '<br>';
echo 'IV : //QxQj7PDMRE1YUVo+mJvQ==' //IV FROM SSH PROGRAM WHICH IS THE RIGHT RETURN;

Мне действительно интересно, где лежит проблема или как это отладить?

Настройки в PHP и C # одинаковы:

PHP-код:

$hasher = "SHA256";
$iterations = 1000;
$keysize = 256;
$ivsize = 128;

C # КОД:

string random_string_pwd = "mypassword";
byte[] passwordBytes = Encoding.UTF8.GetBytes(random_string_pwd);

//var random_salt = new ClientTools();
//string random_string_salt = random_pwd.RndStrings(15);
string random_string_salt = "mysalthereitis";
byte[] Salt = Encoding.UTF8.GetBytes(random_string_salt);

// Hash the password with SHA256
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
AES.KeySize = 256;
AES.BlockSize = 128;

var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);

1

Решение

В PHP вы декодируете соль Base64, но она не кодируется base64:
base64_decode($salt)

В C # вы просто получаете байты соли:
byte[] Salt = Encoding.UTF8.GetBytes(random_string_salt);

В PHP вы используете SHA256
В C # вы используете MSN Rfc2898DeriveBytes, который использует SHA1:
Rfc2898DeriveBytes Class указывает: использование генератора псевдослучайных чисел на основе HMACSHA1.
Использование SHA256 на password bytes не исправляет MSN rfc2898derivebytes. Это проблема MSN, поскольку она не позволяет указать HAMC.

Решение состоит в том, чтобы изменить PHP так, чтобы он просто получал строковые байты в качестве данных, а не пытался и Base64 декодировать то, что не закодировано в Base64.

  1. Как минимум, делайте то же самое на каждом языке
  2. Если вам нужно использовать MSN Rfc2898DeriveBytes, измените PHP HMAC на SHA1.
  3. Не декодируйте Base64 строку, которая не закодирована в Base64, это часто приводит к сбою. На самом деле Base64 расшифровывает мисальтериит
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]