Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.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#_Dictionary_Encryption_Hashtable_Des - Fatal编程技术网

C# 字典键查找问题。应该有比赛的时候没有比赛

C# 字典键查找问题。应该有比赛的时候没有比赛,c#,dictionary,encryption,hashtable,des,C#,Dictionary,Encryption,Hashtable,Des,我正在尝试模拟一个对双DES的中间相遇攻击,其工作原理如下: 所以我在执行MitM攻击,首先用k1的所有可能值加密一个已知的明文m,然后用k2的所有可能值解密一个已知的密文c。然后在这两者之间应该有一个匹配,它给出了k1和k2。我使用的是20位的缩减密钥大小,而不是56位(或64位,这是DES实现实际想要的输入)。我只是在20位后加上零 我已经实现了我认为是正确的解决方案,但没有得到任何匹配 我的两个哈希表: Dictionary<string, string> hashTable

我正在尝试模拟一个对双DES的中间相遇攻击,其工作原理如下:

所以我在执行MitM攻击,首先用k1的所有可能值加密一个已知的明文m,然后用k2的所有可能值解密一个已知的密文c。然后在这两者之间应该有一个匹配,它给出了k1和k2。我使用的是20位的缩减密钥大小,而不是56位(或64位,这是DES实现实际想要的输入)。我只是在20位后加上零

我已经实现了我认为是正确的解决方案,但没有得到任何匹配

我的两个哈希表:

Dictionary<string, string> hashTable = new Dictionary<string, string>();       
Dictionary<string, string> matches = new Dictionary<string, string>();
public static string DES_Encrypt(string input, byte[] key)
{
    DESCryptoServiceProvider desCryptoService = new DESCryptoServiceProvider();

    //Reflection necessary otherwise it complains about a weak key, so bypassing that check
    MethodInfo mi = desCryptoService.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
    object[] Par = { key, desCryptoService.Mode, key, desCryptoService.FeedbackSize, 0 };

    ICryptoTransform trans = mi.Invoke(desCryptoService, Par) as ICryptoTransform;

    byte[] resultArray = trans.TransformFinalBlock(Encoding.Default.GetBytes(input), 0, Encoding.Default.GetBytes(input).Length);
    desCryptoService.Clear();
    return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static string DES_Decrypt(string input, byte[] key)
{
    DESCryptoServiceProvider desCryptoService = new  DESCryptoServiceProvider();

    //Again have to use reflection..
    MethodInfo mi = desCryptoService.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
    object[] Par = { key, desCryptoService.Mode, key, desCryptoService.FeedbackSize, 0 };
    ICryptoTransform trans = mi.Invoke(desCryptoService, Par) as ICryptoTransform;

    byte[] resultArray = trans.TransformFinalBlock(Encoding.Default.GetBytes(input), 0, Encoding.Default.GetBytes(input).Length);
    desCryptoService.Clear();
    return Convert.ToBase64String(resultArray);
}
DESWrapper.desu加密方法:

Dictionary<string, string> hashTable = new Dictionary<string, string>();       
Dictionary<string, string> matches = new Dictionary<string, string>();
public static string DES_Encrypt(string input, byte[] key)
{
    DESCryptoServiceProvider desCryptoService = new DESCryptoServiceProvider();

    //Reflection necessary otherwise it complains about a weak key, so bypassing that check
    MethodInfo mi = desCryptoService.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
    object[] Par = { key, desCryptoService.Mode, key, desCryptoService.FeedbackSize, 0 };

    ICryptoTransform trans = mi.Invoke(desCryptoService, Par) as ICryptoTransform;

    byte[] resultArray = trans.TransformFinalBlock(Encoding.Default.GetBytes(input), 0, Encoding.Default.GetBytes(input).Length);
    desCryptoService.Clear();
    return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static string DES_Decrypt(string input, byte[] key)
{
    DESCryptoServiceProvider desCryptoService = new  DESCryptoServiceProvider();

    //Again have to use reflection..
    MethodInfo mi = desCryptoService.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
    object[] Par = { key, desCryptoService.Mode, key, desCryptoService.FeedbackSize, 0 };
    ICryptoTransform trans = mi.Invoke(desCryptoService, Par) as ICryptoTransform;

    byte[] resultArray = trans.TransformFinalBlock(Encoding.Default.GetBytes(input), 0, Encoding.Default.GetBytes(input).Length);
    desCryptoService.Clear();
    return Convert.ToBase64String(resultArray);
}
加密后,我有一个包含220个条目的hastable。我要做的下一件事是进行解密:

解密:

Dictionary<string, string> hashTable = new Dictionary<string, string>();       
Dictionary<string, string> matches = new Dictionary<string, string>();
public static string DES_Encrypt(string input, byte[] key)
{
    DESCryptoServiceProvider desCryptoService = new DESCryptoServiceProvider();

    //Reflection necessary otherwise it complains about a weak key, so bypassing that check
    MethodInfo mi = desCryptoService.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
    object[] Par = { key, desCryptoService.Mode, key, desCryptoService.FeedbackSize, 0 };

    ICryptoTransform trans = mi.Invoke(desCryptoService, Par) as ICryptoTransform;

    byte[] resultArray = trans.TransformFinalBlock(Encoding.Default.GetBytes(input), 0, Encoding.Default.GetBytes(input).Length);
    desCryptoService.Clear();
    return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static string DES_Decrypt(string input, byte[] key)
{
    DESCryptoServiceProvider desCryptoService = new  DESCryptoServiceProvider();

    //Again have to use reflection..
    MethodInfo mi = desCryptoService.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
    object[] Par = { key, desCryptoService.Mode, key, desCryptoService.FeedbackSize, 0 };
    ICryptoTransform trans = mi.Invoke(desCryptoService, Par) as ICryptoTransform;

    byte[] resultArray = trans.TransformFinalBlock(Encoding.Default.GetBytes(input), 0, Encoding.Default.GetBytes(input).Length);
    desCryptoService.Clear();
    return Convert.ToBase64String(resultArray);
}
当我用当前的填充密钥解密
ciphertext1
时,如果它是正确的密钥,那么结果将是一个中间密码,它已经作为
密钥存在于
哈希表中。所以我执行这个查找。如果存在,我将这两个键保存到另一个哈希表
匹配项中。如果它不存在,我就继续前进

for (int i = 0; i < Math.Pow(2, 20); i++)
{
     string key2 = ToBin(i, 20);
     string paddedKey2 = ToBin(i, 20).PadRight(64, '0');

    //Decrypting ciphertext1 with key2 (64bit padded)
    string intermediaryCipher =
    DESWrapper.DES_Decrypt(ciphertext1,   ConvertBinaryStringToByteArray(paddedKey2));

    var temp = hashTable.FirstOrDefault(x => x.Key == intermediaryCipher);
    if(temp.Key != null)
    {
        matches.Add(temp.Value, key2);
        Console.WriteLine("Found match!");
        Console.ReadKey();
    }

    //Show the current iteration in binary
    Console.WriteLine(ToBin(i, 20));
}
问题:

Dictionary<string, string> hashTable = new Dictionary<string, string>();       
Dictionary<string, string> matches = new Dictionary<string, string>();
public static string DES_Encrypt(string input, byte[] key)
{
    DESCryptoServiceProvider desCryptoService = new DESCryptoServiceProvider();

    //Reflection necessary otherwise it complains about a weak key, so bypassing that check
    MethodInfo mi = desCryptoService.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
    object[] Par = { key, desCryptoService.Mode, key, desCryptoService.FeedbackSize, 0 };

    ICryptoTransform trans = mi.Invoke(desCryptoService, Par) as ICryptoTransform;

    byte[] resultArray = trans.TransformFinalBlock(Encoding.Default.GetBytes(input), 0, Encoding.Default.GetBytes(input).Length);
    desCryptoService.Clear();
    return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static string DES_Decrypt(string input, byte[] key)
{
    DESCryptoServiceProvider desCryptoService = new  DESCryptoServiceProvider();

    //Again have to use reflection..
    MethodInfo mi = desCryptoService.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
    object[] Par = { key, desCryptoService.Mode, key, desCryptoService.FeedbackSize, 0 };
    ICryptoTransform trans = mi.Invoke(desCryptoService, Par) as ICryptoTransform;

    byte[] resultArray = trans.TransformFinalBlock(Encoding.Default.GetBytes(input), 0, Encoding.Default.GetBytes(input).Length);
    desCryptoService.Clear();
    return Convert.ToBase64String(resultArray);
}
我从未得到匹配,因此哈希表查找总是返回一个空的键值对。我不明白为什么。最终它应该匹配,但事实并非如此

问题是否会出现在我试图在
哈希表中查找值的方式上


其他信息:

Dictionary<string, string> hashTable = new Dictionary<string, string>();       
Dictionary<string, string> matches = new Dictionary<string, string>();
public static string DES_Encrypt(string input, byte[] key)
{
    DESCryptoServiceProvider desCryptoService = new DESCryptoServiceProvider();

    //Reflection necessary otherwise it complains about a weak key, so bypassing that check
    MethodInfo mi = desCryptoService.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
    object[] Par = { key, desCryptoService.Mode, key, desCryptoService.FeedbackSize, 0 };

    ICryptoTransform trans = mi.Invoke(desCryptoService, Par) as ICryptoTransform;

    byte[] resultArray = trans.TransformFinalBlock(Encoding.Default.GetBytes(input), 0, Encoding.Default.GetBytes(input).Length);
    desCryptoService.Clear();
    return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static string DES_Decrypt(string input, byte[] key)
{
    DESCryptoServiceProvider desCryptoService = new  DESCryptoServiceProvider();

    //Again have to use reflection..
    MethodInfo mi = desCryptoService.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
    object[] Par = { key, desCryptoService.Mode, key, desCryptoService.FeedbackSize, 0 };
    ICryptoTransform trans = mi.Invoke(desCryptoService, Par) as ICryptoTransform;

    byte[] resultArray = trans.TransformFinalBlock(Encoding.Default.GetBytes(input), 0, Encoding.Default.GetBytes(input).Length);
    desCryptoService.Clear();
    return Convert.ToBase64String(resultArray);
}
为了加密最初的明文和密文,我使用一个伪造的密钥,其中第17位设置为1,所有其他63位设置为0。这对两个键都是如此

这样,当我解密时,我应该可以很快得到匹配,但我不确定问题是否在这里。包括代码:

        private static void GeneratePlaintextCiphertextPairs(out string plainText1, out string plainText2, out string cipherText1, out string cipherText2)
    {
        Random rnd = new Random(Guid.NewGuid().GetHashCode());

        //Generate two random keys of 20 bits padded with 0s to reach 64 bits
        //We need 64 bits because the implementation of DES requires it. Internally,
        //it will only use 56 bits
        byte[] key1 = GenerateRandom64BitPaddedKey(rnd);
        byte[] key2 = GenerateRandom64BitPaddedKey(rnd);

        plainText1 = "Hello Dear World";

        //Perform double DES encryption
        cipherText1 = DESWrapper.DES_Encrypt(
                                DESWrapper.DES_Encrypt(plainText1, key1),
                                key2);

        plainText2 = "Hello Evil World";

        //Perform double DES encryption
        cipherText2 = DESWrapper.DES_Encrypt(
                                DESWrapper.DES_Encrypt(plainText2, key1),
                                key2);
    }

    private static byte[] GenerateRandom64BitPaddedKey(Random rnd)
    {
        short keySize = 64;

        //The first 20bits are of interest, the rest is padded with 0s
        BitArray bitArray = new BitArray(keySize);

        for (int i=0; i<keySize; i++)
        {
            //if(i < 20) { bitArray[i] = rnd.NextDouble() > 0.5; }
            //else { bitArray[i] = false; }
            if (i == 17) { bitArray[i] = true; }
            else { bitArray[i] = false; }
        }

        //Console.WriteLine("In Binary: " + ToDigitString(bitArray));
        byte[] key = new byte[8];
        ReverseBitArray(ref bitArray);     
        bitArray.CopyTo(key, 0);
        return key;            
    }
private static void GeneratePlaintextCiphertextPairs(输出字符串plainText1、输出字符串plainText2、输出字符串cipherText1、输出字符串cipherText2)
{
Random rnd=new Random(Guid.NewGuid().GetHashCode());
//生成两个20位的随机密钥,用0填充以达到64位
//我们需要64位,因为DES的实现需要它,
//它将只使用56位
字节[]键1=GeneratorDomain64BitPaddedKey(rnd);
字节[]键2=GeneratorDomain64BitPaddedKey(rnd);
plainText1=“你好,亲爱的世界”;
//执行双重DES加密
cipherText1=DESWrapper.DES_Encrypt(
DESWrapper.DES_加密(明文1,密钥1),
键2);
plainText2=“你好,邪恶世界”;
//执行双重DES加密
cipherText2=DESWrapper.DES_Encrypt(
DESWrapper.DES_加密(明文2,密钥1),
键2);
}
专用静态字节[]GeneratorDomain64BitPaddedKey(随机rnd)
{
短键大小=64;
//前20位是感兴趣的,其余用0填充
BitArray BitArray=新的BitArray(密钥大小);
对于(int i=0;i 0.5;}
//else{bitArray[i]=false;}
如果(i==17){bitArray[i]=true;}
else{bitArray[i]=false;}
}
//WriteLine(“二进制:+ToDigitString(位数组));
字节[]键=新字节[8];
反向二进制(参考位数组);
位数组.CopyTo(键,0);
返回键;
}

这正是您的问题所在。哈希表逻辑在我看来似乎没有问题。我认为问题出在其他地方。以下是一些想法……1)在GeneratePlaintextCiphertextPairs中,通过对cyphertexts进行双重解密来反转加密。你得到原始值了吗?2) 在GeneratorDomain64BitPaddedKey中,您执行反转tarray(ref bitArray),这会将单个键位移动到另一侧。你的Math.Pow(2,20)真的生成了完全相同的密钥吗?您应该能够在代码中放入一条对于单位随机键为true的if语句,并在if分支中放入一个断点。1。能否向我们提供
ToBin
ConvertBinaryStringToByteArray
的代码?它们可能会导致问题2。为什么要进行字符串转换呢?直接从
long
/
ulong
转换为字节数组表示不是更容易吗?3.在两种方法的末尾使用不同的
Convert.ToBase64String
重载有什么原因吗?这本身不是一个问题,但在我看来,这两者有很多相似的逻辑,可能会留下错误的空间。4.如果您在字典键上使用
FirstOrDefault
,则可能没有正确使用字典DS,这正是您遇到的问题所在。哈希表逻辑对我来说似乎没问题。我想问题出在别的地方。这里有一些想法。。。1) 在GeneratePlaintextCiphertextPairs中,通过双重解密cyphertexts来反转加密。你得到原始值了吗?2) 在GeneratorDomain64BitPaddedKey中,您执行反转tarray(ref bitArray),这会将单个键位移动到另一侧。你的Math.Pow(2,20)真的生成了完全相同的密钥吗?您应该能够在代码中放入一条对于单位随机键为true的if语句,并在if分支中放入一个断点。1。能否向我们提供
ToBin
ConvertBinaryStringToByteArray
的代码?它们可能会导致问题2。为什么要进行字符串转换呢?直接从
long
/
ulong
转换为字节数组表示不是更容易吗?3.在两种方法的末尾使用不同的
Convert.ToBase64String
重载有什么原因吗?这本身不是一个问题,但在我看来,这两者有很多相似的逻辑,可以为e留下空间