Как я могу реализовать CBC-MAC с DES?
Я должен реализовать метод генерации MAC-CBC в C# с некоторой информацией об алгоритме криптографии. Вот что у меня есть:
- Я должен использовать DES.
- Ключ
byte[] {11, 11, 11, 11, 11, 11, 11, 11}
- Данные (16 байт) должны быть зашифрованы 8-байтовыми частями. Первые 8 байтов зашифрованы с использованием
Instance Vector = new byte[8]
(8 байтов со значением 0). (CBC?) - последние 8 байтов зашифрованного значения должны быть преобразованы в шестнадцатеричную строку. это результат, который я должен отправить.
С этой информацией я реализовал следующий метод:
public static string Encrypt(byte[] data)
{
var IV = new byte[8];
var key = new byte[] { 11, 11, 11, 11, 11, 11, 11, 11 };
var result = new byte[16];
// Create DES and encrypt.
var des = DES.Create();
des.Key = key;
des.IV = IV;
des.Padding = PaddingMode.None;
des.Mode = CipherMode.CBC;
ICryptoTransform cryptoTransform = des.CreateEncryptor(key, IV);
cryptoTransform.TransformBlock(data, 0, 16, result, 0);
// Get the last eight bytes of the encrypted data.
var lastEightBytes = new byte[8];
Array.Copy(result, 8, lastEightBytes, 0, 8);
// Convert to hex.
var hexResult = string.Empty;
foreach (byte ascii in lastEightBytes)
{
int n = (int)ascii;
hexResult += n.ToString("X").PadLeft(2, '0');
}
return hexResult;
}
Пример необработанных данных, которые они предоставили мне: input=byte[] {0, 6, 4, 1, 6, 4, 1, 7, E, E, F, F, F, F, B, B)
который должен вернуть вывод значения: A7CBFB3C730B059C
, Это означает, что последние восемь байтов зашифрованных данных должны быть: byte[] {167, 203, 251, 60, 115, 11, 05, 156}
,
Но, к сожалению, используя вышеуказанный метод, я получаю: 32D91200D0007632
, это означает, что мои зашифрованные данные не верны. (последние восемь байт сгенерированного зашифрованного значения моего метода byte[] {50, 207, 18, 0, 208, 0, 118, 50}
).
Могу ли я узнать, что мне нужно сделать, чтобы добраться до A7CB...? Я делаю что-то неправильно?
2 ответа
CBC-MAC требует нулевого вектора инициализации. Намного лучше указать IV явно:
var IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
Вы говорите, что ваш ключ byte[] { 11, 11, 11, 11, 11, 11, 11, 11 }
эти байты в шестнадцатеричном или в базе 10? Вы можете попробовать:
var key = new byte[] { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 };
и посмотрим, будет ли это работать лучше.
Проект Mono имеет универсальную реализацию MAC-CBC, которая должна работать с любым SymmetricAlgorithm - даже если он используется внутренне только для реализации MACTripleDES.
Вы можете найти лицензионный исходный код MIT.X11 здесь. Используйте его как есть или сравните с вашим собственным кодом.