我想确定 MAC(消息认证码) CBC chiper(Ansi x9.9),我发现了一个根据周期计算MAC的样本,每一轮加密的重新计算必须与下一轮纯文本块进行异或,并且结果应该被加密以用于下一步,并且该循环重复4次,直到最后一个加密值必须作为MAC返回。
加密密钥= 0123456789abcdef
该文本是“7654321现在是时间”的ASCII代码。
文字= 37363534333231204e6f77206873207468652074696d6520666f7220
TIME --- PLAIN TEXT --------------- DES INPUT BLOCK -------- DES OUTPUT BLOCK
1 ---- 3736353433323120 -------- 3736353433323120 -------- 21fb193693a16c28
2 ---- 4e6f772068732074 -------- 6f946e16fad24c5c -------- 6c463f0cb7167a6f
3 ---- 68652074696d6520 -------- 04231f78de7b1f4f -------- 956ee891e889d91e
4 ---- 666f722000000000 -------- f3019ab1e889d91e -------- f1d30f6849312ca4
我试图实现这个示例。在第一步,我得到了与样本相同的结果,但是对于下一步,我的Des加密函数返回不同的resutl作为样本的第2步。我使用硬件设备加密每个Des输入块,它返回与样本返回相同的DES输出块。要么我找到了另一个DES实现样本here,它也会重新获得正确的加密。但我在msdn上使用microsft示例的应用程序返回步骤2,3和4的错误结果,除了步骤1.这是我的代码:
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);
}
答案 0 :(得分:2)
您应该重复使用密码,而不是每次使用密钥和IV重新初始化密码。
主叫代码:
var IV = new byte[8];//empty byte array
var key = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
var data = Encoding.ASCII.GetBytes("7654321 Now is the time for ");
DES DESalg = DES.Create();
DESalg.Mode = CipherMode.CBC;
DESalg.Padding = PaddingMode.None;
ICryptoTransform crypt = DESalg.CreateEncryptor(key, IV);
var result = new byte[8];
int LoopCount = data.Length / 8;
for (int i = 0; i < LoopCount; i++)
{
Console.WriteLine("=============Round {0}==============", i + 1);
byte[] part = new byte[8];
Array.Copy(data, i * 8, part, 0, 8);
Console.WriteLine("Plain text : {0}", ByteArrayToString(part));
part = XorArray(part, result);
Console.WriteLine("DES INPUT : {0}", ByteArrayToString(part));
result = EncryptPart(crypt, part);
}
int remain = data.Length % 8;
if (remain != 0)
{
Console.WriteLine("===========Final Round==============");
byte[] LastPart = new byte[8];//
Array.Copy(data, data.Length - remain, LastPart, 0, remain);
Console.WriteLine("Plain text : " + ByteArrayToString(LastPart));
LastPart = XorArray(LastPart, result);
Console.WriteLine("DES INPUT : " + ByteArrayToString(LastPart));
result = EncryptPart(crypt, LastPart);
}
Console.WriteLine("Result: {0}", ByteArrayToString(result));
修改后的加密部分方法:
public static byte[] EncryptPart(ICryptoTransform crypt, byte[] toEncrypt)
{
try
{
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream,
crypt,
CryptoStreamMode.Write);
cStream.Write(toEncrypt, 0, toEncrypt.Length);
cStream.FlushFinalBlock();
byte[] ret = mStream.ToArray();
cStream.Close();
mStream.Close();
Console.WriteLine("DES OUTPUT : " + ByteArrayToString(ret));
return ret;
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
}
结果:
=============Round 1==============
Plain text : 3736353433323120
DES INPUT : 3736353433323120
DES OUTPUT : 21fb193693a16c28
=============Round 2==============
Plain text : 4e6f772069732074
DES INPUT : 6f946e16fad24c5c
DES OUTPUT : 6c463f0cb7167a6f
=============Round 3==============
Plain text : 68652074696d6520
DES INPUT : 04231f78de7b1f4f
DES OUTPUT : 956ee891e889d91e
===========Final Round============
Plain text : 666f722000000000
DES INPUT : f3019ab1e889d91e
DES OUTPUT : f1d30f6849312ca4
Result: f1d30f6849312ca4
这些值与您指定的值以及此specification
中的值相匹配答案 1 :(得分:0)
错误的根本原因来自FIPS 113文档提供的十六进制字符串。
文字:“7654321现在是时候了”
十六进制(错误):“37363534333231204e6f7720 68 73207468652074696d6520666f7220”
十六进制(正确):“37363534333231204e6f7720 69 73207468652074696d6520666f7220”