Шифрую строку в php, как расшифровать в C#

Шифрую в PHP так

$key = "11111";
$data = 'Test';
$method = "AES-128-CBC";
$encrypted = openssl_encrypt($data, $method, $key);
echo $encrypted;

Подскажите пожалуйста как расшифровать это это в C#. Нашел метод, но у меня тут что то не сходиться

public static string Decrypt(string cipherData, string keyString, string ivString)
{
byte[] key = Encoding.UTF8.GetBytes(keyString);
byte[] iv  = Encoding.UTF8.GetBytes(ivString);

try
{
    using (var rijndaelManaged =
           new RijndaelManaged {Key = key, IV = iv, Mode = CipherMode.CBC})
    using (var memoryStream = 
           new MemoryStream(Convert.FromBase64String(cipherData)))
    using (var cryptoStream =
           new CryptoStream(memoryStream,
               rijndaelManaged.CreateDecryptor(key, iv),
               CryptoStreamMode.Read))
    {
        return new StreamReader(cryptoStream).ReadToEnd();
    }
}
catch (CryptographicException e)
{
    Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
    return null;
}
// You may want to catch more exceptions here...
}

Ответы (1 шт):

Автор решения: Alex Netkachov

Во-первых, не похоже, что бы часть шифрования была корректной. Согласно комментариям на странице https://www.php.net/manual/en/function.openssl-encrypt.php - третий параметр является ключём, а не паролем.

Пример правильного ключа:

$key = "395f426c0e5bd914375837483b791d80854dd9a19dd86fd189e94ccade60c5b8";

Ключ и iv получают из пароля применением некотого алгоритма. Например pbkdf2.

Таким образом, правильный алгоритм:

  1. Сгенерируйте salt.
  2. Из пароля и salt сгенерируйте ключ и iv.
  3. Запишите salt в данные, затем запишите закриптованные данные.

В моем менеджере паролей pwd есть пример запаковки и распаковки текста полностью совместимый с openssl https://github.com/AlexAtNet/pwd/blob/master/pwd.csx:

static Aes CreateAes(byte[] salt, string password) {
   var aes = Aes.Create();
   (aes.Mode, aes.Padding) = (CipherMode.CBC, PaddingMode.PKCS7);
   // 10000 and SHA256 are defaults for pbkdf2 in openssl
   using var rfc2898 = new Rfc2898DeriveBytes(password, salt, 10000, HashAlgorithmName.SHA256);
   (aes.Key, aes.IV) = (rfc2898.GetBytes(32), rfc2898.GetBytes(16));
   return aes;
}

static string Decrypt(string password, byte[] data) {
   using var stream = new MemoryStream(data);
   if ("Salted__" != Encoding.ASCII.GetString(ReadBytes(stream, 8)))
      throw new FormatException("Expecting the data stream to begin with Salted__.");
   using var aes = CreateAes(ReadBytes(stream, 8), password);
   using var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
   using var cryptoStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read);
   using var reader = new StreamReader(cryptoStream);
   return reader.ReadToEnd();
}

Расшифровывает файлы зашифрованные openssl aes-256-cbc -d -salt -pbkdf2.

→ Ссылка