Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中的DES初始化向量#_C#_Encryption_Des - Fatal编程技术网

C# C语言中的DES初始化向量#

C# C语言中的DES初始化向量#,c#,encryption,des,C#,Encryption,Des,我正在尝试解密(使用DES算法)C代码中来自第三方的数据。这里和其他地方都有很多例子帮助了我。问题是我不知道如何使用“初始化向量” 第三方提供了一个用于命令行的工具(DES.EXE,我相信它是libdes库v4.01的现成版本),它只需要您提供加密密钥。所以,我可以用这个工具很好地解密。但是,我不希望从我的代码中生成一个进程来运行该工具 我的问题是如何生成/找到初始化向量。我99.9%的确信这可以通过查看其他帖子来实现,但我无法理解。我和第三方谈过,他们说他们不支持这种方法。非常感谢您的帮助。有

我正在尝试解密(使用DES算法)C代码中来自第三方的数据。这里和其他地方都有很多例子帮助了我。问题是我不知道如何使用“初始化向量”

第三方提供了一个用于命令行的工具(DES.EXE,我相信它是libdes库v4.01的现成版本),它只需要您提供加密密钥。所以,我可以用这个工具很好地解密。但是,我不希望从我的代码中生成一个进程来运行该工具

我的问题是如何生成/找到初始化向量。我99.9%的确信这可以通过查看其他帖子来实现,但我无法理解。我和第三方谈过,他们说他们不支持这种方法。非常感谢您的帮助。

有关分组密码中使用的不同操作模式的说明,请参阅。如果您使用的是ECB模式,即逐块加密消息,则不需要初始化向量(IV)。也许您必须检查DES库是否设置ECB模式/禁用其他模式

如果他们不使用ECB模式,你需要静脉注射,你就无法“猜”到它。在大多数情况下,静脉注射不一定要保密,所以移动静脉注射不是问题。

我花了一些时间(约2天)来解决同样的问题。将des.exe“重写”为C#。最后,我得到了libdes源代码,并对逻辑进行了反向工程

初始化向量为全部(8)个零。也就是说,新字节[8]应该可以

然而,诀窍可能是如何将字符串密码转换为8字节长的密钥。如果您使用的是简单DES(不是三重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};
}
公共类libdespasswordconverter
{
公共字节[]密码tokey(字符串密码)
{
如果(密码==null)
抛出新的ArgumentNullException(“密码”);
如果(密码==“”)
抛出新的ArgumentException(“密码”);
var key=新字节[8];
for(int i=0;i4)和0x0f));
c=((c>2)和0x33));
c=((c>1)和0x55));
键[7-(i%8)]^=(字节)c;
}
}
添加奇偶校验(密钥);
var target=新字节[8];
var密码缓冲区=
Encoding.ASCII.GetBytes(password).Concat(新字节[8]).Take(password.Length+(8-(password.Length%8))%8.ToArray();
var des=des.Create();
var encryptor=des.CreateEncryptor(key,key);
用于(int x=0;x
(一些libdes代码被重用,尽管我必须自己找出DES的“校验和”部分)


最后一个陷阱是,libdes使用了非标准的填充机制。它几乎与ISO的填充机制类似,但最后一个字节不是添加的字节数,而是8-这个数字。我将padding属性设置为None,然后自己处理填充。

对于下面的答案,需要初始化向量。我相信第三方使用CBC模式。就像我说的,如果他们使用IV,他们必须给你,因为你猜不到。不知何故,命令行工具不需要他们提供des.exe。你只需输入密钥。这就是为什么我认为它是可派生的。谢谢你的输入。你解决了这个问题吗?我有完全相同的问题。我有Java和C的解决方案#。如果有人需要,请在此处发送消息,我将发布一个答案。在Java中使用非常类似的语言,您不知道您的填充评论为我节省了多少痛苦…请编辑一个答案,我错投了反对票。我将投赞成票。感谢您提供的解决方案。我有Java和C#的解决方案。如果有人需要,请在此处和此处发送消息我会发布一个答案。