c # — PHP эквивалент шифрования .net AES

Я работаю над интеграцией обмена данными с моим клиентом, и данные, которые они мне отправляют, зашифрованы с использованием их C # encrypt метод (ниже).

Мое приложение работает на PHP 5.3, и мне нужен эквивалентный код для расшифровки отправляемых данных. У меня есть код PHP, но он не сможет правильно расшифровать данные клиента.

Очевидно, я делаю какую-то ошибку в моих методах шифрования / дешифрования, ключе IV или чем-то еще. Кто-нибудь может заметить ошибку?

Благодарю.

Код C # (от моего клиента):

using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

public class Program
{
public static void Main()
{
var text = "this is a plain string";
var enc = Program.Encrypt(text);
Console.WriteLine(enc);
Console.WriteLine(Program.Decrypt(enc));
}

public static string Encrypt(string clearText)
{
var EncryptionKey = "1234567890123456";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
byte[] IV = new byte[15];
var rand = new Random();
rand.NextBytes(IV);
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, IV);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}

clearText = Convert.ToBase64String(IV) + Convert.ToBase64String(ms.ToArray());
}
}

return clearText;
}

public static string Decrypt(string cipherText)
{
var EncryptionKey = "1234567890123456";
byte[] IV = Convert.FromBase64String(cipherText.Substring(0, 20));
cipherText = cipherText.Substring(20).Replace(" ", "+");
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, IV);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}

cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}

return cipherText;
}
}

PHP код у меня есть:

public function encrypt($plainText)
{
$secretKey = '1234567890123456';

return rtrim(
base64_encode(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_256,
$secretKey, $plainText,
MCRYPT_MODE_ECB,
mcrypt_create_iv(
mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB
),
MCRYPT_RAND)
)
), "\0");
}

public function decrypt($encodedData)
{
$secretKey = '1234567890123456';

return rtrim(
mcrypt_decrypt(
MCRYPT_RIJNDAEL_256,
$secretKey,
base64_decode($encodedData),
MCRYPT_MODE_ECB,
mcrypt_create_iv(
mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB
),
MCRYPT_RAND
)
), "\0");
}

-3

Решение

Кто-нибудь может заметить ошибку?

Да, и большая из них не твоя вина запутанный API mcrypt снова поражает.

Тем не менее, здесь действительно много ошибок.

return rtrim( // unnecessary
base64_encode(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_256, // Not AES
$secretKey, $plainText,
MCRYPT_MODE_ECB, // BAD, use MCRYPT_MODE_CBC or 'ctr' instead
mcrypt_create_iv(
mcrypt_get_iv_size(      // unless you're going make this
MCRYPT_RIJNDAEL_256, // configurable, you should just
MCRYPT_MODE_ECB      // hard-code this as an integer
),
MCRYPT_RAND) // BAD, use MCRYPT_DEV_URANDOM
)
), "\0");

Если вы собираетесь сгенерировать IV, о нем следует сообщить, чтобы ваш получатель мог успешно расшифровать тот же первый блок. Код C # делает это, а PHP нет.

С точки зрения инженерии криптографии вы должны рассмотреть, как в C # land, так и в PHP, развертывание протокола Encrypt затем Authenticate. Увидеть этот пост в блоге о шифровании и аутентификации. Также, весь криптографический код, который вы когда-либо писали, вероятно, сломан.

10

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

Похоже, что PHP Script использует неправильный режим:
https://msdn.microsoft.com/en-us/library/system.security.cryptography.symmetricalgorithm.mode%28v=vs.110%29.aspx
Функции C # не устанавливают никакого режима, поэтому по умолчанию используется CBC.
Вместо этого PHP-часть использует ECB, что не только неправильно, но и небезопасно.

0

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