MAC(メッセージ認証コード) CBCチッパー(Ansi x9.9)をまとめたいのですが、サイクルに基づいてMACを計算するサンプルを見つけました。各ラウンドで、暗号化された再利用は次のラウンドのプレーンテキストブロックとXORである必要があります。結果は次のステップに使用されるように作成する必要があり、最後の暗号化された値がMACとして返される必要があるまで、このサイクルが4回繰り返されます。
暗号化キー=0123456789abcdef
テキストは「7654321今が」のASCIIコードです。
テキスト=37363534333231204e6f77206873207468652074696d6520666f7220
時間---プレーンテキスト---------------DES入力ブロック--------DES出力ブロック
1 ---- 3736353433323120 -------- 3736353433323120 -------- 21fb193693a16c28
2 ---- 4e6f772068732074 -------- 6f946e16fad24c5c -------- 6c463f0cb7167a6f
3 ---- 68652074696d6520 -------- 04231f78de7b1f4f -------- 956ee891e889d91e
4 ---- 666f722000000000 -------- f3019ab1e889d91e -------- f1d30f6849312ca4
このサンプルを実装してみました。最初のステップでサンプルと同じ結果が得られましたが、次のステップでは、Des暗号化関数がサンプルの2番目のステップとは異なる結果を返します。ハードウェアデバイスを使用して各Des入力ブロックを暗号化しました。これは、サンプルの戻り値と同じDES出力ブロックを返します。ここで別のDES実装サンプルを見つけましたが、これも正しい暗号化を返します。しかし、msdnでmicrosftの例を使用する私のアプリは、ステップ1を除くステップ2、3、および4で誤った結果を返します。これが私のコードです。
public byte[] EncryptPart(byte[] toEncrypt, byte[] Key, byte[] IV)
{
try
{
MemoryStream mStream = new MemoryStream();
DES DESalg = DES.Create();
DESalg.Mode = CipherMode.CBC;
DESalg.Padding = PaddingMode.None;
CryptoStream cStream = new CryptoStream(mStream,
DESalg.CreateEncryptor(Key, IV),
CryptoStreamMode.Write);
cStream.Write(toEncrypt, 0, toEncrypt.Length);
cStream.FlushFinalBlock();
byte[] ret = mStream.ToArray();
cStream.Close();
mStream.Close();
return ret;
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
}
そしてここで私はその機能を使用しました
var IV = new byte[8];//empty byte array
var key = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
var result = new byte[8];
int LoopCount = data.Length / 8;
for (int i = 0; i < LoopCount; i++)
{
byte[] Part= new byte[8];
Array.Copy(data, i * 8, Part, 0, 8);
Part = XorArray(Part, result);
result = EncryptPart(Part, key, IV);
}
int remain=data.Length % 8;
if (remain != 0)
{
byte[] LastPart = new byte[8];//
Array.Copy(data, data.Length - remain, LastPart, 0, remain);
LastPart=XorArray(LastPart, result);
result = EncryptPart(LastPart, key, IV);
}