Mcrypt и base64 с PHP и C#

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

Строка: это тест

Ключ: 1234567812345678

Зашифрованная строка PHP: ybUaKwQlRNwOjJhxLWtLYQ ==

C# зашифрованная строка: r2YjEFPyDDacnPmDFcGTLA ==

C# функции

static string Encrypt(string plainText, string key)
{
    string cipherText;
    var rijndael = new RijndaelManaged()
    {
        Key = Encoding.UTF8.GetBytes(key),
        Mode = CipherMode.ECB,
        BlockSize = 128,
    };
    ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key, rijndael.IV);

    using (var memoryStream = new MemoryStream())
    {
        using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
        {
            using (var streamWriter = new StreamWriter(cryptoStream))
            {
                streamWriter.Write(plainText);
                streamWriter.Flush();
            }
            cipherText = Convert.ToBase64String(memoryStream.ToArray());
            //cryptoStream.FlushFinalBlock();
        }
    }
    return cipherText;
}

private static string Decrypt(string cipherText, string key)
{
    string plainText;
    byte[] cipherArray = Convert.FromBase64String(cipherText);
    var rijndael = new RijndaelManaged()
    {
        Key = Encoding.UTF8.GetBytes(key),
        Mode = CipherMode.ECB,
        BlockSize = 128
    };
    ICryptoTransform decryptor = rijndael.CreateDecryptor(rijndael.Key, rijndael.IV);

    using (var memoryStream = new MemoryStream(cipherArray))
    {
        using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
        {
            using (var streamReader = new StreamReader(cryptoStream))
            {
                plainText = streamReader.ReadToEnd();
            }
        }
    }
    return plainText;
}

PHP функции

function string_encrypt($string, $key) {
    $crypted_text = mcrypt_encrypt(
                            MCRYPT_RIJNDAEL_128, 
                            $key, 
                            $string, 
                            MCRYPT_MODE_ECB
                        );
    return base64_encode($crypted_text);
}

function string_decrypt($encrypted_string, $key) {
    return mcrypt_decrypt(
                    MCRYPT_RIJNDAEL_128, 
                    $key, 
                    base64_decode($encrypted_string), 
                    MCRYPT_MODE_ECB
                    );
}

Я не очень хорош в C# и знаю, что функция PHP работает нормально. Итак, что-то должно быть сделано с функциями C#. Может быть строка для шифрования должна быть преобразована в латинские символы.

1 ответ

C# по умолчанию выполняет заполнение Rijndael и использует PKCS7.

Это означает, что вы должны дополнить свою сторону PHP согласно PKCS7, код ниже должен работать:

function string_encrypt($string, $key) {

  $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
  $padding = $block - (strlen($string) % $block);
  $string .= str_repeat(chr($padding), $padding);

    $crypted_text = mcrypt_encrypt(
                            MCRYPT_RIJNDAEL_128, 
                            $key, 
                            $string, 
                            MCRYPT_MODE_ECB
                        );
    return base64_encode($crypted_text);
}

Для получения дополнительной информации см. Первый ответ здесь

Я должен также добавить, что если вы хотите изменить сторону C# и не использовать заполнение, сделайте вместо этого модификацию ниже и оставьте сторону PHP в покое:

static string Encrypt(string plainText, string key)
{
  string cipherText;
  var rijndael = new RijndaelManaged()
  {
    Key = Encoding.UTF8.GetBytes(key),
    Mode = CipherMode.ECB,
    BlockSize = 128,
    Padding = PaddingMode.Zeros,
  };
  ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key, null);

  using (var memoryStream = new MemoryStream())
  {
    using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
    {
      using (var streamWriter = new StreamWriter(cryptoStream))
      {
        streamWriter.Write(plainText);
        streamWriter.Flush();
      }
      //cipherText = Convert.ToBase64String(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(memoryStream.ToArray())));
      cipherText = Convert.ToBase64String(memoryStream.ToArray());
      //cryptoStream.FlushFinalBlock();
    }
  }
  return cipherText;
}
Другие вопросы по тегам