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;
}