Array.Resize(ref Key, 32);
Array.Resize(ref IV, 16);
Шифрование на C# с последующей дешифровкой на PHP
Шифрую на C#
Код:
byte[] Key = Encoding.Default.GetBytes("key12345678");
byte[] IV = Encoding.Default.GetBytes("key12345678");
RijndaelManaged RMCrypto = new RijndaelManaged();
RMCrypto.Mode = CipherMode.ECB;
RMCrypto.Padding = PaddingMode.Zeros;
RMCrypto.KeySize = 256;
ICryptoTransform Encryptor = RMCrypto.CreateEncryptor(Key, IV);
CryptoStream Crypt = new CryptoStream(fs, Encryptor, CryptoStreamMode.Write);
using (StreamWriter sw = new StreamWriter(Crypt))
{
sw.Write("Recording data");
sw.Flush();
}
byte[] IV = Encoding.Default.GetBytes("key12345678");
RijndaelManaged RMCrypto = new RijndaelManaged();
RMCrypto.Mode = CipherMode.ECB;
RMCrypto.Padding = PaddingMode.Zeros;
RMCrypto.KeySize = 256;
ICryptoTransform Encryptor = RMCrypto.CreateEncryptor(Key, IV);
CryptoStream Crypt = new CryptoStream(fs, Encryptor, CryptoStreamMode.Write);
using (StreamWriter sw = new StreamWriter(Crypt))
{
sw.Write("Recording data");
sw.Flush();
}
Расшифровываю на PHP
Код:
$data = file_get_contents("data.txt");
echo mcrypt_decrypt(MCRYPT_RIJNDAEL_256, "key12345678", $data, MCRYPT_MODE_ECB, "key12345678");
echo mcrypt_decrypt(MCRYPT_RIJNDAEL_256, "key12345678", $data, MCRYPT_MODE_ECB, "key12345678");
Подскажите, где копать :)
Заранее спасибо
Цитата:
Encoding.Default
по поводу функи mcrypt_decrypt ничего сказать не могу. но она все равно как то текстовый ключ переводит в ключ из 32 байт (может быть хэш какой-то иди просто паддинг текста и в какой кодировке?). скорее всего из-за этого и не расшифровывает правильно.
Если зашифровывать средствами PHP, то всё дешифруется нормально. Значит в C# коде я накосячил. Не очень понял, для чего нужен IV и нужен ли он?
Код:
перед строчкой RijndaelManaged RMCrypto = new RijndaelManaged();
Цитата:
Не очень понял, для чего нужен IV и нужен ли он?
вектор инициализации. как он будет использоваться зависит от режима шифрования. его можно использовать как расширение для ключа.
кстати режим ECB лучше не использовать. и в этом режиме IV не используется. каждый блок данных шифруется ключем а в самом конце дополняется.
Результат поменялся, но по прежнему не читабелен. Может по другому-то как-то надо ключ переводить?
Зато вот с 256 не хочет и не знаю баг это или нет
mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
вернет 32, когда размер блока должен быть равен 16. тут косяк в PHP он неправильно (де)шифрует с MCRYPT_RIJNDAEL_256
нашел:
Цитата:
Understanding PHP AES Encryption
You would think that MCRYPT_RIJNDAEL_256 specifies 256-bit encryption,
but that is wrong. The three choices specify the block-size to be used
with Rijndael encryption. They say nothing about the key size (i.e. strength)
of the encryption.
Thus, if you specify MCRYPT_RIJNDAEL_256, your encrypted output will always
be a multiple of 32 bytes (i.e. 256 bits). If you specify MCRYPT_RIJNDAEL_128,
your encrypted output will always be a multiple of 16 bytes.
Note: Strictly speaking, AES is not precisely Rijndael (although in practice
they are used interchangeably) as Rijndael supports a larger range of block
and key sizes; AES has a fixed block size of 128 bits and a key size of
128, 192, or 256 bits, whereas Rijndael can be specified with key and block
sizes in any multiple of 32 bits, with a minimum of 128 bits and a maximum of
256 bits.
In summary: If you want to be AES compliant, always choose MCRYPT_RIJNDAEL_128.
C#
Код:
...
byte[] Key = Encoding.Default.GetBytes("key12345678");
byte[] IV = null;
Array.Resize(ref Key, 32);
Array.Resize(ref IV, 32);
RijndaelManaged RMCrypto = new RijndaelManaged();
RMCrypto.Mode = CipherMode.ECB;
RMCrypto.Padding = PaddingMode.Zeros;
RMCrypto.KeySize = 128;
ICryptoTransform Encryptor = RMCrypto.CreateEncryptor(Key, IV);
...
byte[] Key = Encoding.Default.GetBytes("key12345678");
byte[] IV = null;
Array.Resize(ref Key, 32);
Array.Resize(ref IV, 32);
RijndaelManaged RMCrypto = new RijndaelManaged();
RMCrypto.Mode = CipherMode.ECB;
RMCrypto.Padding = PaddingMode.Zeros;
RMCrypto.KeySize = 128;
ICryptoTransform Encryptor = RMCrypto.CreateEncryptor(Key, IV);
...
PHP
Код:
$data = file_get_contents("filename");
echo mcrypt_decrypt(MCRYPT_RIJNDAEL_128, "key12345678", $data, MCRYPT_MODE_ECB);
echo mcrypt_decrypt(MCRYPT_RIJNDAEL_128, "key12345678", $data, MCRYPT_MODE_ECB);
Выдает бяку опять
Код:
byte[] Key = Encoding.Default.GetBytes("key12345678");
Array.Resize(ref Key, 16); // Array.Resize(ref Key, RMCrypto.KeySize >> 3);
RijndaelManaged RMCrypto = new RijndaelManaged();
RMCrypto.Mode = CipherMode.ECB;
RMCrypto.Padding = PaddingMode.Zeros;
RMCrypto.KeySize = 128;
RMCrypto.Key = Key;
ICryptoTransform Encryptor = RMCrypto.CreateEncryptor();
Array.Resize(ref Key, 16); // Array.Resize(ref Key, RMCrypto.KeySize >> 3);
RijndaelManaged RMCrypto = new RijndaelManaged();
RMCrypto.Mode = CipherMode.ECB;
RMCrypto.Padding = PaddingMode.Zeros;
RMCrypto.KeySize = 128;
RMCrypto.Key = Key;
ICryptoTransform Encryptor = RMCrypto.CreateEncryptor();
И вообще Encoding.Default лучше заменить на явное указание какой-нибудь кодировки. Например UTF8, только конечно в PHP эту кодировку надо учитывать. UTF8 хороша тем, что если набор символов будет только ASCII, то она их представит как есть.
И в представлении ключа как массива байтов и в
Цитата:
new StreamWriter(Crypt, Encoding.x)
Огромное спасибо :) Теперь всё работает как надо