DES初始化向量在C# [英] DES Initialization Vector in C#

查看:1003
本文介绍了DES初始化向量在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图解密(使用DES算法)来自在C#代码中的第三方数据。有很多在这里和其他地方的例子来帮助我。问题是,我不知道用什么为初始化向量。

I am trying to decrypt (using the DES algorithm) data that comes from a third party in C# code. There are plenty of examples here and elsewhere that have helped me out. The problem is that I don't know what to use for the 'initialization vector'.

第三方提供的命令行(DES.EXE,我相信在使用工具外的现成的版本所libdes库V4的0.01)只需要你提供一个加密密钥。所以,我可以解密罚款的工具。不过,我宁愿不生成一个进程来运行从我的代码的工具。

The third party supplied a tool for use on the command line (DES.EXE, which I believe is an out-of-the-box build of the libdes library v4.01) which only requires that you supply an encryption key. So, I can decrypt fine with the tool. However, I would rather not spawn a process to run the tool from my code.

我的问题是如何生成/发现,初始化向量。我相信99.9%,它可以从寻找其他职位做,但我无法弄清楚。我跟第三方,他们说他们不支持这种做法。任何帮助将不胜感激。

My question is how do I generate/find that initialization vector. I am 99.9% sure it can be done from looking at other posts but I can't figure it out. I talked to the third party and they said they do not support that approach. Any help would be greatly appreciated.

推荐答案

我花了一些时间(〜2天)理清了同样的问题。 重写des.exe到C#。最后,我得到了libdes来源和反向工程的逻辑。

I spent some time (~2 days) to sort out the same issue. "Rewriting" des.exe into C#. In the end I got the libdes sources and reverse-engineered the logic.

初始化向量都(8)零。即新的字节[8]应该做的。

The initialization vector are all (8) zeros. I.e. new byte[8] should do.

不过,招可能是如何将字符串密码转换为8字节长的密钥。如果您使用简单的DES(未三重DES),这个代码可以为你做的伎俩:

However, the trick may be how to convert a string password into 8 bytes long key. If you're using simple DES (not Triple DES), this code may do the trick for you:

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 校验的一部分我自己)。

(Some pieces of libdes code reused, though I had to figure out the DES "checksum" part myself).

最后一个缺陷是,libdes使用非标准的填充机制。这几乎就像了ISO之一,但最后一个字节不是加字节,但8数 - 这个号码。我设置填充属性设置为无,并处理填充自己。

The last pitfall is, that libdes uses non-standard padding mechanism. It's almost like the ISO one, but the last byte is not the number of added bytes but 8 - this number. I set the Padding property to None and handled the padding myself.

这篇关于DES初始化向量在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆