예제 #1
0
        public int FindBlockSize()
        {
            var aggregated = new Dictionary <int, float>();
            int start      = 10;
            int end        = 32;
            int blocks     = 4;

            for (int i = start; i < end * 3; i++)
            {
                Base64 encrypted = eo.EncryptConsistentKey(new String('A', i), unknownString);
                var    keys      = HammingDistance.FindDistancePerKeySize(start, end, encrypted.Decode(), blocks);
                foreach (var kvp in keys)
                {
                    if (aggregated.ContainsKey(kvp.Key))
                    {
                        aggregated[kvp.Key] += kvp.Value;
                    }
                    else
                    {
                        aggregated.Add(kvp.Key, kvp.Value);
                    }
                }
            }

            var possibleKey = aggregated.OrderBy(x => x.Value).Take(1);

            return(possibleKey.Select(x => x.Key).Single());
        }
        public void FindDistancePerKeySize()
        {
            string source          = "abcdefghabcdefgh";
            int    correctKeySize  = 8;
            int    hammingDistance = 0;

            var result = HammingDistance.FindDistancePerKeySize(2, 10, source);

            Assert.AreEqual(result[correctKeySize], hammingDistance);
        }
 public void FindDistancePerKeySizeWithInvalidBlockNumber()
 {
     try
     {
         string source = "abcdef";
         var    result = HammingDistance.FindDistancePerKeySize(2, 10, source, 3);
         Assert.Fail();
     }
     catch (ArgumentException)
     {
         return;
     }
 }
예제 #4
0
        public string[] BreakXorFile(Base64 data, int startKeySize = 2, int endKeySize = 60, int numberOfBlocks = 2)
        {
            int take = 10;

            Hex source           = data;
            var possibleKeySizes = HammingDistance.FindDistancePerKeySize(startKeySize, endKeySize, source.ToString(), numberOfBlocks).OrderBy(x => x.Value).Select(x => x.Key).Take(take);

            foreach (var possibleKeySize in possibleKeySizes)
            {
                StringBuilder sb = new StringBuilder();

                var transposedBlocks = source.CreateAndTransposeBlocks(possibleKeySize);
                var decryptedBlocks  = new List <string>();

                bool foundOne = false;

                foreach (var block in transposedBlocks)
                {
                    var decrypted = this.TryDecrypt(block);
                    var c         = CharacterCounter.FindKey(decrypted);
                    if (c == '\0')
                    {
                        if (foundOne)
                        {
                            sb.Append('?');
                            decryptedBlocks.Add(decrypted['A']);
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        foundOne = true;
                        sb.Append(c);
                        decryptedBlocks.Add(decrypted[c]);
                    }
                }

                string key = sb.ToString();

                if (key.Length > 0)
                {
                    StringBuilder decrypted = new StringBuilder();
                    for (int i = 0; i < decryptedBlocks[0].Length; i++)
                    {
                        foreach (string block in decryptedBlocks)
                        {
                            if (i < block.Length)
                            {
                                decrypted.Append(block[i]);
                            }
                        }
                    }

                    return(new string[] { key, decrypted.ToString() });
                }
            }

            return(new string[] { "", "" });
        }