我正在尝试使用C#代码解密(使用DES算法)来自第三方的数据。这里和其他地方有很多例子可以帮助我。问题是我不知道用于“初始化向量”的内容。
第三方提供了一个在命令行上使用的工具(DES.EXE,我认为它是libdes库v4.01的开箱即用版本),它只需要你提供一个加密密钥。所以,我可以使用该工具解密。但是,我宁愿不从我的代码中生成一个运行该工具的进程。
我的问题是如何生成/找到初始化向量。我99.9%肯定可以通过查看其他帖子来完成,但我无法弄明白。我和第三方谈过,他们说他们不支持这种做法。任何帮助将不胜感激。
答案 0 :(得分:1)
我花了一些时间(约2天)来解决同样的问题。 “重写”des.exe到C#。最后,我获得了libdes源并对逻辑进行了反向设计。
初始化向量都是(8)零。即新字节[8]应该做。
但是,技巧可能是如何将字符串密码转换为8字节长密钥。如果你使用的是简单的DES(不是Triple DES),这段代码可能适合你:
public class LibDesPasswordConvertor
{
public byte[] PasswordToKey(string password)
{
if (password == null)
throw new ArgumentNullException("password");
if (password == "")
throw new ArgumentException("password");
var key = new byte[8];
for (int i = 0; i < password.Length; i++)
{
var c = (int)password[i];
if ((i % 16) < 8)
{
key[i % 8] ^= (byte)(c << 1);
}
else
{
// reverse bits e.g. 11010010 -> 01001011
c = (((c << 4) & 0xf0) | ((c >> 4) & 0x0f));
c = (((c << 2) & 0xcc) | ((c >> 2) & 0x33));
c = (((c << 1) & 0xaa) | ((c >> 1) & 0x55));
key[7 - (i % 8)] ^= (byte)c;
}
}
AddOddParity(key);
var target = new byte[8];
var passwordBuffer =
Encoding.ASCII.GetBytes(password).Concat(new byte[8]).Take(password.Length + (8 - (password.Length % 8)) % 8).ToArray();
var des = DES.Create();
var encryptor = des.CreateEncryptor(key, key);
for (int x = 0; x < passwordBuffer.Length / 8; ++x)
{
encryptor.TransformBlock(passwordBuffer, 8 * x, 8, target, 0);
}
AddOddParity(target);
return target;
}
private void AddOddParity(byte[] buffer)
{
for (int i = 0; i < buffer.Length; ++i)
{
buffer[i] = _oddParityTable[buffer[i]];
}
}
private static byte[] _oddParityTable = {
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
}
(重用了一些libdes代码,但我必须自己弄清楚DES“校验和”部分。)
最后一个陷阱是,libdes使用非标准的填充机制。它几乎就像ISO一样,但最后一个字节不是添加的字节数,而是8 - 这个数字。我将Padding属性设置为None并自行处理填充。
答案 1 :(得分:0)
有关分组密码中使用的不同操作模式的说明,请参阅http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation。如果您使用的ECB模式只是逐块加密消息,则不需要初始化向量(IV)。也许您必须检查您的DES库以设置ECB模式/禁用其他人。
如果他们没有使用ECB模式你需要IV,你不能“猜测”它。在大多数情况下,IV不必是秘密的,因此移动它不是问题。