2

128 ビットの Rijndael を使用してリクエストを暗号化するために必要な Web サービス クライアントを実装しています。RijndaelManaged クラスは Silverlight には存在しないため、次のアドバイスに従いました

結果は、最初の 32 文字 (128 ビット)、正確なブロック サイズに対してのみ、得られた結果が正しい (つまり、RijndaelManaged を使用して得たものと同じ) ということです。ここで何が間違っているのかわかりません。私の .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;
}
4

2 に答える 2

0

.NET バージョンは AES に EBC モードを使用しますが、Silverlight バージョンは CBC を使用します。ECB モードでは初期化ベクトルが使用されず、CBC モードでは初期化ベクトルがゼロであるため、最初の出力ブロックは両方のバージョンで同じです。CBC モードでは、各ブロックは前のブロックと XOR され (最初のブロックは初期化ベクトルと XOR されます)、暗号化されますが、EBC モードでは各ブロックはそのまま暗号化されます。

于 2011-11-09T14:09:08.187 に答える
0

IVを本当にクリアしているかどうかは明らかではありません。バイト配列としてフェッチしてからクリアしていますが、IV プロパティが内部値をコピーしてから返すかどうかはわかりません。私はこれを使用します:

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

(ちなみに、パラメータとローカル変数に PascalCase を使用するのもやめます。通常の規則では、非定数変数にはキャメルケースを使用します。)

編集:コードが実際に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 は変更されません。

于 2011-03-18T17:21:18.617 に答える