1

ここで初期化ベクトルの適切な使用についていくつかのスレッドを読み、項目ごとにランダムな IV を使用するようにいくつかの既存のコードをリファクタリングしている最中です。

データのブロブとキーを取得する方法があり、提供されたキーとランダムな IV を使用してブロブを暗号化する必要があります。

public static byte[] AesEncrypt(byte[] data, byte[] key)
{
    byte[] output = new byte[0];

    Console.WriteLine("Data: {0}", Encoding.ASCII.GetString(data));
    Console.WriteLine("Key: {0}", BitConverter.ToString(key));

    using (AesCryptoServiceProvider acp = new AesCryptoServiceProvider())
    {
        acp.GenerateIV();
        byte[] vector = acp.IV;
        using (ICryptoTransform trans = acp.CreateEncryptor(key, vector))
        {

            Console.WriteLine("Vector: {0}", BitConverter.ToString(vector));
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, trans, CryptoStreamMode.Write))
                using(BinaryWriter bw = new BinaryWriter(cs))
                {
                    bw.Write(vector);
                    bw.Write(data);
                    cs.FlushFinalBlock();
                    output = ms.ToArray();
                }
            }
        }
    }
    Console.WriteLine("Output: {0}", BitConverter.ToString(output));
    return output;
}

その意図は、同じデータ入力とキーに対して同じ暗号文が生成されるのを防ぐことです。残念ながら、コンソール出力には毎回異なる IV が生成されていることが示されますが、同じデータとキーを使用してメソッドを複数回呼び出すと、同じ暗号文が生成されます。

Data: 4761739001010010
Key: 7C-26-D9-6B-A1-FC-9E-67-9A-A2-7D-5F-52-5C-09-54-FE-DD-A5-C6-90-DD-0F-B3-CC-E2-7E-0E-4F-2D-2E-97
Vector: ED-02-6E-C6-B3-7A-74-66-4B-E5-47-23-16-D6-87-3B
Output: CB-F7-93-16-64-24-E2-F0-81-00-99-DA-97-F1-46-43-7D-F7-C4-AC-2E-C8-D4-D9-F1-7C-67-6E-F3-14-F0-4F-C7-1B-02-AE-41-4C-6B-B9-80-3A-64-4B-14-10-60-1B

Data: 4761739001010010
Key: 7C-26-D9-6B-A1-FC-9E-67-9A-A2-7D-5F-52-5C-09-54-FE-DD-A5-C6-90-DD-0F-B3-CC-E2-7E-0E-4F-2D-2E-97
Vector: 3E-3B-32-FB-82-03-03-9F-54-96-67-AA-29-5E-09-C4
Output: CB-F7-93-16-64-24-E2-F0-81-00-99-DA-97-F1-46-43-7D-F7-C4-AC-2E-C8-D4-D9-F1-7C-67-6E-F3-14-F0-4F-C7-1B-02-AE-41-4C-6B-B9-80-3A-64-4B-14-10-60-1B

これがどこで間違っているのか考えていますか?

4

3 に答える 3

1

暗号化にバイナリ ライターを使用したことはありません。これは私が疲れたコードであり、うまく機能しているようです

public static byte[] AesEncrypt(string toEncrypt, byte[] key)
{
    byte[] output = new byte[0];

    var data = Encoding.UTF8.GetBytes(toEncrypt);

    Console.WriteLine("Data: {0}", Encoding.ASCII.GetString(data));
    Console.WriteLine("Key: {0}", BitConverter.ToString(key));

    using (AesCryptoServiceProvider acp = new AesCryptoServiceProvider())
    {
        acp.GenerateIV();
        byte[] vector = acp.IV;
        using (ICryptoTransform trans = acp.CreateEncryptor(key, vector))
        {

            Console.WriteLine("Vector: {0}", BitConverter.ToString(vector));
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, trans, CryptoStreamMode.Write))
                //using (BinaryWriter bw = new BinaryWriter(cs))
                {
                    cs.Write(data, 0, data.Length);
                    //bw.Write(vector);
                    //bw.Write(data);
                    cs.FlushFinalBlock();
                    output = ms.ToArray();
                }
            }
        }
    }
    Console.WriteLine("Output: {0}", BitConverter.ToString(output));
    return output;
}

ただし、復号化部分はテストしていません。この例のようにランダムな IV を使用している場合、後でそれをどのように復号化する予定なのかわかりません。

于 2015-04-24T15:02:36.320 に答える
1

あなたが見るものは、実際には正しい動作です......

問題は、暗号化ストリームに最初に書き込むものがベクトルであることです。

このリンクを見ると: https://security.stackexchange.com/questions/44442/using-aescryptoserviceprovider-in-c-should-using-an-incorrect-iv-mangle-just-t

CBCモードでの最初の操作は、提供されたデータ(あなたの場合はベクトル)と提供されたベクトルをXORすることであると説明しています。したがって、基本的に、提供するベクトルが何であれ、暗号化される最初のデータ (XOR 操作後) は、以下を0 参照して構成されます: http://en.wikipedia.org/wiki/Exclusive_or

次に使用されるベクトルは、最初に暗号化されたデータ ブロックになるため、0キーで暗号化されます。そのため、提供するベクトルに違いは見られません。

この行にコメントするだけの場合:

bw.Write(vector);

期待どおりの動作が表示されます。

于 2015-04-24T15:11:20.347 に答える