Использование шифрования RijndaelManaged в Silverlight - PullRequest
2 голосов
/ 18 марта 2011

Я внедряю клиент веб-сервиса, который необходим для шифрования запроса с использованием 128-битного Rijndael. Поскольку класс RijndaelManaged не существует в Silverlight, я последовал совету здесь: Это обсуждалось здесь: AesManaged и RijndaelManaged

В результате получается, что результат, который я получаю, является правильным (я имею в виду, то же самое, что я получаю, используя RijndaelManaged) только для первых 32 символов (128 бит), точно размер блока. Я не могу понять, что я делаю здесь не так. Моя реализация .Net (RijndaelManaged) выглядит так:

private static byte[] Encrypt(byte[] PlainTextBytes, byte[] KeyBytes, string InitialVector)
{
    byte[] InitialVectorBytes = Encoding.UTF8.GetBytes(InitialVector);
    RijndaelManaged SymmetricKey = new RijndaelManaged();
    SymmetricKey.Mode = CipherMode.ECB;
    SymmetricKey.Padding = PaddingMode.PKCS7;
    SymmetricKey.BlockSize = 128;
    ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes);
    MemoryStream MemStream = new MemoryStream();
    CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write);
    CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
    CryptoStream.FlushFinalBlock();
    byte[] CipherTextBytes = MemStream.ToArray();
    MemStream.Close();
    CryptoStream.Close();

    return CipherTextBytes;
}

, в то время как мой Silverlight:

private string Encrypt(byte[] PlainTextBytes, byte[] KeyBytes, string InitialVector)
{
    AesManaged SymmetricKey = new AesManaged();
    byte[] InitialVectorBytes = SymmetricKey.IV;
    //NOTE- because Mode and Padding don't exist in AESManaged for Silverlight, I have to do the padding myself
    //for an empty InitalVector (which is my case)
    for (int i = 0; i < InitialVectorBytes.Length; i++) InitialVectorBytes[i] = 0;
    SymmetricKey.BlockSize = 128;
    ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes);
    MemoryStream MemStream = new MemoryStream();
    CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write);
    CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
    CryptoStream.FlushFinalBlock();
    byte[] CipherTextBytes = MemStream.ToArray();
    MemStream.Close();
    CryptoStream.Close();

    return CipherTextBytes;
}

Ответы [ 2 ]

0 голосов
/ 09 ноября 2011

Ваша версия .NET использует режим EBC ​​для AES, а версия Silverlight использует CBC.Первый выходной блок одинаков в обеих версиях, поскольку в режиме ECB вектор инициализации не используется, а в режиме CBC вектор инициализации равен нулю.В режиме CBC каждый блок имеет XOR с предыдущим блоком (первый блок XOR с вектором инициализации), а затем шифруется, а в режиме EBC каждый блок шифруется как есть.

0 голосов
/ 18 марта 2011

Не ясно, что вы действительно очищаете IV.Вы извлекаете его как массив байтов, а затем очищаете его, но я не знаю точно, копирует ли свойство IV внутреннее значение перед его возвратом.Я бы использовал это:

SymmetricKey.BlockSize = 128;
SymmetricKey.IV = new byte[SymmetricKey.BlockSize / 8];

(кстати, я бы также прекратил использовать PascalCase для параметров и локальных переменных. Обычное соглашение - использовать camelCase для непостоянных переменных.)

РЕДАКТИРОВАТЬ: Пример кода, чтобы продемонстрировать, как ваш код на самом деле не меняет IV:

AesManaged aes = new AesManaged();
byte[] iv = aes.IV;
iv[0] = 1;
iv[1] = 2;
Console.WriteLine(BitConverter.ToString(iv));      
Console.WriteLine(BitConverter.ToString(aes.IV));

Пример вывода:

01-02-01-1B-6E-05-B8-2A-C0-86-17-EF-A2-80-60-7B
D8-48-01-1B-6E-05-B8-2A-C0-86-17-EF-A2-80-60-7B

Другими словами, изменение значений вмассив не действительно изменяет IV.

...