コード例 #1
0
        static void Main(string[] args)
        {
            //Example Enciphered Text
            const string cipherText = "Ar op chmrivv tfh ofvx nyneiksfnv cxsvu dc ysxjvv zszg di lgqg rhoagg kltl M'xv fxwr vlvgari fzxj mp dc farf vzxj wkegx. \"Olgeiowv afy ywin cmdw gtzxbumbzrz sra frx,\" zi vfpw ei, \"llwm jiovquwv vyem spn klx hiqgpx ar vyml ostch aszge'x ash vyi tvzcextyiu kltl cql'zx zef.\"";

            //Example of how to execute a known plaintext attack
            _log.Info("-------- KNOWN PLAINTEXT ATTACK --------");
            var possibleKeys = KnownPlaintextAttack.AttackWithKnownPlaintext(cipherText, "the");

            foreach (var key in possibleKeys)
            {
                _log.InfoFormat("Possible Key: {0}", key);
                _log.InfoFormat(VigenereEngine.Decipher(cipherText, key));
            }

            //Example of how to execute a Kasiski/Babbage Analysis & Attack
            _log.Info("-------- KASISKI ATTACK --------");
            var likelyKeyLengths = Kasiski.KasiskiExamination(cipherText);

            foreach (var keyLength in likelyKeyLengths)
            {
                _log.InfoFormat("Attempting hack with key length {0} ({1} possible keys)", keyLength, Math.Pow(Convert.ToDouble(keyLength), Convert.ToDouble(Constants.NumMostFreqLetters)));
                var foundKey = KasiskiAttack.AttackWithKeyLength(cipherText, keyLength);

                if (!string.IsNullOrEmpty(foundKey))
                {
                    _log.InfoFormat("Decrypted Text: {0}", new Vigenere().Decipher(cipherText, foundKey));
                    System.Console.ReadKey();
                    return;
                }
            }
        }
コード例 #2
0
        public void FindRepeatSequencesSpacings_Test()
        {
            var result1 =
                Kasiski.FindRepeatSequencesSpacings(
                    "PPQCAXQVEKGYBNKMAZUYBNGBALJONITSZMJYIMVRAGVOHTVRAUCTKSGDDWUOXITLAZUVAVVRAZCVKBQPIWPOU");

            var expected = new Dictionary <string, List <int> >()
            {
                { "YBN", new List <int> {
                      8
                  } },
                { "AZU", new List <int> {
                      48
                  } },
                { "VRA", new List <int> {
                      8, 32, 24
                  } }
            };

            CollectionAssert.AreEqual(expected["YBN"], result1["YBN"]);
            CollectionAssert.AreEqual(expected["AZU"], result1["AZU"]);
            CollectionAssert.AreEqual(expected["VRA"], result1["VRA"]);

            Assert.AreEqual(expected.Count, result1.Count);
        }
コード例 #3
0
        public void TestEncode()
        {
            Kasiski kasiski = new Kasiski();
            IEnumerable <ValueTuple <int, int, double> > check = kasiski.Decode("LFWKIMJCLPSISWKHJOGLKMVGURAGKMKMXMAMJCVXWUYLGGIISW" +
                                                                                "ALXAEYCXMFKMKBQBDCLAEFLFWKIMJCGUZUGSKECZGBWYMOACFV" +
                                                                                "MQKYFWXTWMLAIDOYQBWFGKSDIULQGVSYHJAVEFWBLAEFLFWKIM" +
                                                                                "JCFHSNNGGNWPWDAVMQFAAXWFZCXBVELKWMLAVGKYEDEMJXHUXD" +
                                                                                "AVYXL");

            Assert.IsNotNull(check);
        }
コード例 #4
0
        public void KasiskiExamination_Test()
        {
            var result1 =
                Kasiski.KasiskiExamination(
                    "PPQCAXQVEKGYBNKMAZUYBNGBALJONITSZMJYIMVRAGVOHTVRAUCTKSGDDWUOXITLAZUVAVVRAZCVKBQPIWPOU");

            var expected = new List <int> {
                2, 4, 8
            };

            CollectionAssert.AreEqual(expected, result1);
        }
コード例 #5
0
        public IEnumerable <ValueTuple <int, double> > GetKasiskiResult(string encodedText, string alphabet)
        {
            var repository = new Repository();
            var result     = repository.GetKasiskiResult(encodedText);

            if (ReferenceEquals(result, null))
            {
                var kasiski = new Kasiski(alphabet);
                var res     = kasiski.Decode(encodedText);
                result = repository.AddKasiskiResult(encodedText, res);
            }
            return(result.Select(item => (item.Size, item.Probability)));
        }
コード例 #6
0
        public void GetUsefulFactors_Test()
        {
            var result1 = Kasiski.GetUsefulFactors(48);

            var expected = new List <int>()
            {
                2,
                3,
                4,
                6,
                8,
                12,
                16
            };

            CollectionAssert.AreEqual(expected, result1);
        }
コード例 #7
0
        public void GetNthSubkeysLetters_Test()
        {
            var result1 = Kasiski.GetNthSubkeysLetters(1, 3, "ABCABCABC");

            Assert.AreEqual("AAA", result1);

            var result2 = Kasiski.GetNthSubkeysLetters(2, 3, "ABCABCABC");

            Assert.AreEqual("BBB", result2);

            var result3 = Kasiski.GetNthSubkeysLetters(3, 3, "ABCABCABC");

            Assert.AreEqual("CCC", result3);

            var result4 = Kasiski.GetNthSubkeysLetters(1, 5, "ABCDEFGHI");

            Assert.AreEqual("AF", result4);

            var result5 = Kasiski.GetNthSubkeysLetters(1, 3, "ABC ABC ABC");

            Assert.AreEqual("AAA", result5);
        }
コード例 #8
0
        /// <summary>
        ///     Performs a Kasiski attack provided a given key length
        /// </summary>
        /// <param name="cipherText"></param>
        /// <param name="keyLength"></param>
        /// <returns></returns>
        public static string AttackWithKeyLength(string cipherText, int keyLength)
        {
            var cipher        = new Vigenere();
            var allFreqScores = new List <Dictionary <char, int> >();

            for (var i = 1; i < keyLength + 1; i++)
            {
                var nthLetters = Kasiski.GetNthSubkeysLetters(i, keyLength, cipherText.ToUpper());

                var frequencyScore = new Dictionary <char, int>();
                foreach (var letter in Constants.Letters)
                {
                    var decryptedText = cipher.Decipher(nthLetters, Char.ToString(letter));

                    var score = Frequency.EnglishFreqMatchScore(decryptedText);
                    frequencyScore.Add(letter, score);
                }

                //Sort the dictionary by factor ocurrences descending
                var sortedCommonFactors = (from entry in frequencyScore orderby entry.Value descending select entry)
                                          .Take(4)
                                          .ToDictionary(pair => pair.Key, pair => pair.Value);

                allFreqScores.Add(sortedCommonFactors);
            }

            //Print our possible keys
            var position     = 1;
            var possibleKeys = new List <char[]>();

            foreach (var freq in allFreqScores)
            {
                _log.InfoFormat("Possible letters for letter {0} of the key: ", position);
                var possibleKeyOutput = new StringBuilder();
                var keyStore          = new char[freq.Keys.Count];
                var keyPosition       = 0;
                foreach (var keyPossible in freq.Keys)
                {
                    possibleKeyOutput.AppendFormat("{0}\t", keyPossible);
                    keyStore[keyPosition] = keyPossible;
                    keyPosition++;
                }
                possibleKeys.Add(keyStore);
                _log.InfoFormat(possibleKeyOutput.ToString());
                position++;
            }

            var keyCombinations = Combinator.Combinations(possibleKeys);

            var keyFound = false;
            var key      = string.Empty;

            //Go through the possible keys with the given freqency and determine if they produce
            //an English sentence.
            Parallel.ForEach(keyCombinations, (possibleKey, loopState) =>
            {
                //Stop processing if we find the possible key
                if (keyFound)
                {
                    loopState.Break();
                }

                _log.DebugFormat("Attempting with key: {0}", possibleKey);

                var decryptAttempt = cipher.Decipher(cipherText, possibleKey.ToString());

                if (!English.IsEnglish(decryptAttempt))
                {
                    return;
                }

                _log.InfoFormat("Found Possible Decryption Key: {0}", possibleKey);
                keyFound = true;
                key      = possibleKey.ToString();
            }
                             );

            return(key);
        }