예제 #1
0
 public WordsCompleter(string[] words, Dictionary<char, char> substitutions, Storage.Languages language)
 {
     this.originWords = words;
     this.originSubs = substitutions;
     this.substitutions = substitutions;
     dictionary = Dictionary.Create(Storage.GetLangChar(language).Dictionary, x => x.Length);
 }
예제 #2
0
        public static CrackResult[] Attack(string ciphertext, Cipher[] ciphers, Storage.Languages language)
        {
            var crackResults = GetCrackResults(ciphertext, ciphers, language);

            LangCharacteristic langChar = Storage.GetLangChar(language);
            var results = crackResults.OrderBy(x => Analyse.SimilarityIndex(x.opentext, langChar)).ToArray();

            return results;
        }
예제 #3
0
        public void Attack(string ciphertext, Cipher[] ciphers, Storage.Languages language)
        {
            GetCrackResults(ciphertext, ciphers, language, crackResults =>
                {

                    LangCharacteristic langChar = Storage.GetLangChar(language);
                    var results = crackResults.Where(x => x != null)
                        .OrderBy(x => Analyse.SimilarityIndex(x.opentext, langChar))
                        .ToArray();

                    results = FixVigenere(results);

                    finish(results.First());
                });
        }
예제 #4
0
        /// <summary>
        /// Provede útok testováním všech dostupných klíčů 
        /// a následně vybere nejpravděpodobnější variantu.
        /// </summary>
        /// <param name="packet"></param>
        /// <returns></returns>
        public List<string> BruteForceAttack(string ciphertext, Storage.Languages language)
        {
            Dictionary<char, double> probability = new Dictionary<char, double>();
            Caesar caesar = new Caesar();
            string opentext;

            Analyse.DoAlphabet(letter =>
            {
                opentext = caesar.Decrypt(ciphertext, letter.ToString());
                probability[letter] = Analyse.SimilarityIndex(Analyse.NormalizeText(opentext, Analyse.TextTypes.WithoutSpacesLower), Storage.GetLangChar(language));
            });

            var resultPacket = probability.OrderBy(x => x.Value).ToArray()[0].Key;

            return new List<string>() { resultPacket.ToString() };
        }
예제 #5
0
        /// <summary>
        /// Provede frekvenční analýzu na slovech, tj. text musí obsahovat mezery
        /// jako hranice pro slova.
        /// </summary>
        /// <param name="ciphertext">Šifrový text</param>
        /// <param name="language">Jazyk, který byl text zašifrován</param>
        /// <returns>Seznam možných klíčů</returns>
        public List<string> FrequencyAnalysisWithSpaces(string ciphertext, Storage.Languages language)
        {
            string key;
            string[] words = TextAnalysis.ToWords(ciphertext);
            UniqueWords uniqueWords = new UniqueWords(Storage.GetLangChar(language).UniqueWords);

            var result = uniqueWords.GetLettersSubst(words);

            if (result != null)
            {
                WordsCompleter completer = new WordsCompleter(words, result, language);
                var subst = completer.Complete();
                key = GetKey(subst);
            }
            else
            {
                throw new Exceptions.MatchNotFound();
            }

            return new List<string>() { key };
        }
예제 #6
0
        private static List<CrackResult> GetCrackResults(string ciphertext, Cipher[] ciphers, Storage.Languages language)
        {
            List<CrackResult> results = new List<CrackResult>();

            foreach (var cipher in ciphers)
            {
                try
                {
                    var keys = cipher.Crack(ciphertext, 0, language);
                    if (keys.Count > 0)
                    {
                        var result = new CrackResult();
                        result.key = keys[0];
                        result.opentext = cipher.Decrypt(ciphertext, result.key);
                        result.cipher = cipher;
                        results.Add(result);
                    }
                }
                catch (Exceptions.MatchNotFound)
                { }
            }

            return results;
        }
예제 #7
0
        private List<string> BruteForceAttack(string ciphertext, Storage.Languages language, int[] keysLength)
        {
            ciphertext = Analyse.NormalizeText(ciphertext, Analyse.TextTypes.WithoutSpacesLower);
            Caesar caesar = new Caesar();
            Dictionary<int, string> crackedKeys = new Dictionary<int, string>();

            foreach(int keyLength in keysLength)
            {
                char[][] splitedChars = new char[keyLength][];

                for (int i = 0; i < keyLength; i++)
                    splitedChars[i] = GetNthChars(ciphertext, keyLength, i);

                char[] crackKeys = new char[keyLength];

                for (int i = 0; i < keyLength; i++)
                {
                    try
                    {
                        crackKeys[i] = caesar.Crack(Analyse.NormalizeText(new string(splitedChars[i]), Analyse.TextTypes.WithoutSpacesUpper), Caesar.TriangleID, language).First()[0];
                    }
                    catch (Exceptions.MatchNotFound)
                    {
                        crackKeys[i] = '?';
                    }
                }

                crackedKeys[keyLength] = new string(crackKeys);
            }

            var possKeys = crackedKeys.Where(x => x.Value.Length > 0).Select(x => x.Value).ToArray();

            Dictionary<string, double> simIndexes = new Dictionary<string, double>();

            for (int i = 0; i < possKeys.Length; i++)
            {
                string openttext = Decrypt(ciphertext, possKeys[i]);
                double simIndex = Analyse.SimilarityIndex(openttext, Storage.GetLangChar(language));
                simIndexes[possKeys[i]] = simIndex;
            }

            var result = simIndexes.OrderBy(x => x.Value).Select(x => x.Key).ToList();

            return result;
        }
예제 #8
0
 /// <summary>
 /// Metoda použitá v testování
 /// </summary>
 /// <param name="ciphertext"></param>
 /// <param name="language"></param>
 /// <returns></returns>
 public string UnitTextFrequency(string ciphertext, Storage.Languages language)
 {
     return FrequencyAnalysisWithSpaces(ciphertext, language)[0];
 }
예제 #9
0
 /// <summary>
 /// Provede útok na šifru pomocí frekvenční analýzy. 
 /// </summary>
 /// <param name="packet">Balíček obsahující zašifrovaný text</param>
 /// <returns>Balíček obsahující dešifrovaný text a klíč</returns>
 private List<string> FrequencyAnalysis(string ciphertext, Storage.Languages language)
 {
     int spacesCount = ciphertext.Count(' ');
     if (spacesCount > 0 && (ciphertext.Length / spacesCount < 15))
     {
         return FrequencyAnalysisWithSpaces(ciphertext, language);
     }
     else
     {
         throw new Exceptions.MatchNotFound();
     }
 }
예제 #10
0
        private void GetCrackResults(string ciphertext, Cipher[] ciphers, Storage.Languages language, Action<CrackResult[]> afterCrack)
        {
            int threadsCount = ciphers.Length;
            CrackResult[] results = new CrackResult[threadsCount];
            bool[] syncArray = new bool[threadsCount].Fill(false);
            object progressLockObject = new object();
            object endTestLockObject = new object();

            threadsCount.Times(i =>
                {
                    Thread thread = new Thread(() =>
                        {
                            try
                            {
                                var currentCipher = ciphers[i];
                                var keys = currentCipher.Crack(ciphertext, 0, language);
                                if (keys.Count > 0)
                                {
                                    var crackResult = new CrackResult();
                                    crackResult.key = keys[0];
                                    crackResult.opentext = currentCipher.Decrypt(ciphertext, crackResult.key);
                                    crackResult.cipher = currentCipher;
                                    results[i] = crackResult;
                                }
                                else
                                {
                                    throw new Exceptions.MatchNotFound();
                                }

                                lock (progressLockObject)
                                {
                                    progress();
                                }
                            }
                            catch (Exceptions.MatchNotFound)
                            {
                                lock (progressLockObject)
                                {
                                    progress();
                                }
                            }

                            lock (endTestLockObject)
                            {
                                syncArray[i] = true;
                                if (syncArray.All(x => x))
                                {
                                    afterCrack(results);
                                }
                            }
                        });

                    thread.Priority = ThreadPriority.Lowest;
                    thread.IsBackground = true;
                    addThread(thread);
                    thread.Start();
                });
        }
예제 #11
0
 /// <summary>
 /// Násilné dešifrování zašifrovaného textu bez znalosti klíče.
 /// </summary>
 /// <param name="CipherText">Text, který se pokoušíme dešifrovat</param>
 /// <returns>Otevřený text</returns>
 public List<string> Crack(string ciphertext, int attackType, Storage.Languages language)
 {
     return CrackMethods[attackType](ciphertext, language);
 }
예제 #12
0
        /*********************************************/
        /*********** One big word attack *************/
        /*********************************************/
        private List<string> BigWordAttack(string ciphertext, Storage.Languages language)
        {
            ciphertext = Analyse.NormalizeText(ciphertext, Analyse.TextTypes.WithoutSpacesLower);
            var keyLengths = GetKeyLengths(ciphertext);
            LangCharacteristic lang = Storage.GetLangChar(language);
            List<string> possKeys = new List<string>();

            foreach (int keyLength in keyLengths)
            {

                string[] columns = GetDecryptColumns(ciphertext, keyLength);
                string[] rows = GetRows(columns);

                DictionaryAttack attack = new DictionaryAttack();
                string[] keys = attack.GetKeys(rows, lang.TopWords);
                string[] orderedKeys = OrderKeys(keys, ciphertext, lang);
                if (orderedKeys.Length > 0)
                    possKeys.Add(orderedKeys[0]);
            }

            if (possKeys.Count > 0)
            {
                string[] finalKeys = OrderKeys(possKeys.ToArray(), ciphertext, lang);
                return finalKeys.ToList();
            }

            throw new Exceptions.MatchNotFound();
        }
예제 #13
0
        /// <summary>
        /// Crackovací metoda, která se nejprve pokusí zjistit délku klíče
        /// a následně se pokusí prolomit šifru standardně.
        /// </summary>
        /// <param name="ciphertext"></param>
        /// <param name="language"></param>
        /// <returns></returns>
        private List<string> TestKeyLengthAttack(string ciphertext, Storage.Languages language)
        {
            KeyLength keyLength = new KeyLength();
            var keysLength = keyLength.GetKeyLength(ciphertext).Take(6).ToArray();

            if (keysLength.Length == 0)
                keysLength = new int[MaxKeyLength - 2].Fill(x => x + 2);

            return BruteForceAttack(ciphertext, language, keysLength);
        }
예제 #14
0
        /*********** Brute force attack **************/
        private List<string> BruteForceAttack(string ciphertext, Storage.Languages language)
        {
            int keyLength = 7;
            string[] columns = GetDecryptColumns(ciphertext, keyLength);
            string[] rows = GetRows(columns);
            string firstLine = rows[0];

            var variations = Combinatorics.Permutation(firstLine.ToCharArray().ToList());

            int res = variations.Count(x => x.Implode() == "namstar");

            List<string> canonicalKey = Storage.Letters.Take(keyLength).ToList();
            var permKeys = Combinatorics.Permutation(canonicalKey);
            Dictionary<string, string> possTexts = new Dictionary<string, string>();

            foreach (var key in permKeys)
            {
                string k = key.Implode();
                possTexts[k] = Decrypt(ciphertext, k);
            }

            var langChar = Storage.GetLangChar(language);
            var result = possTexts.OrderBy(x => Analyse.SimilarityIndex(x.Value, langChar)).Take(10).ToDictionary(x => x.Key, x => x.Value);

            throw new Exceptions.MatchNotFound();
        }
예제 #15
0
        /*********** First Letters Attack ************/
        // TODO: ostatní jazyky nemají TopWords!!!
        private List<string> FirstLettersAttack(string ciphertext, Storage.Languages language)
        {
            var keyLengths = GetKeyLengths(ciphertext);
            int minWordLength = 3;
            int testStringLength = 20;
            double minSuccess = (double)20 / (double)1300;

            foreach (int keyLength in keyLengths)
            {
                if (keyLength < 10)
                    continue;

                string[] columns = GetDecryptColumns(ciphertext, keyLength);
                string[] rows = GetRows(columns);
                string[] sentence = rows.Take((int)Math.Ceiling((double)testStringLength / (double)keyLength)).ToArray();
                var lang = Storage.GetLangChar(language);
                DictionaryAttack firstAttack = new DictionaryAttack();
                string[] topWords = lang.TopWords.Where(x => x.Length >= minWordLength).ToArray();
                string[] topTopWords = topWords.Take(100).ToArray();
                var keys = firstAttack.CrossFilter(sentence, topWords);
                var opentexts = new string[keys.Length];

                for (int i = 0; i < keys.Length; i++)
                    opentexts[i] = Decrypt(ciphertext, keys[i]);

                Dictionary<string, int> probabilities = new Dictionary<string, int>();

                for (int i = 0; i < keys.Length; i++)
                    probabilities[keys[i]] = Analyse.WordsContains(opentexts[i], topTopWords);

                var resultKeys = probabilities.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
                var isthere = opentexts.Where(x => x.Contains("oznamenipodala")).Count() == 1;

                if(resultKeys.Count > 0 && ((double)resultKeys.First().Value / (double)1300) > minSuccess)
                    return resultKeys.Take(10).Select(x => x.Key).ToList();
            }

            throw new Exceptions.MatchNotFound();
        }
예제 #16
0
 private List<string> BruteForceAttack(string ciphertext, Storage.Languages language)
 {
     int[] keysLength = new int[MaxKeyLength - 2].Fill(x => x + 2);
     return BruteForceAttack(ciphertext, language, keysLength);
 }
예제 #17
0
        /// <summary>
        /// Provede útok na šifru pomocí frekvenční analýzy. 
        /// </summary>
        /// <param name="packet">Balíček obsahující zašifrovaný text</param>
        /// <returns>Balíček obsahující dešifrovaný text a klíč</returns>
        private List<string> FrequencyAnalysis(string ciphertext, Storage.Languages language)
        {
            int spacesCount = ciphertext.Count(' ');
            if (spacesCount > 0 && (ciphertext.Length / spacesCount < 15))
            {
                return FrequencyAnalysisWithSpaces(ciphertext, language);
            }
            else
            {
                /*var lang = Storage.GetLangChar(language);
                TopLetters topLettersAttack = new TopLetters();
                var topLetters = topLettersAttack.Get(ciphertext, lang);

                SamePatternAttack samePattern = new SamePatternAttack();
                var substitutions = samePattern.GetKey(ciphertext, lang, topLetters);
                var key = GetReverseKey(substitutions);
                return new List<string>() { key };*/

                throw new Exceptions.MatchNotFound();
            }
        }
예제 #18
0
        /*********** test key length attack *******************/
        private List<string> TestKeyLength(string ciphertext, Storage.Languages language)
        {
            int averageKeyLength = 10;
            int minSentenceLength = 40;
            var keyLengths = Maths.AllDivisors(ciphertext.Length);
            var orderKeyLengths = keyLengths.OrderBy(x => Math.Abs(x - averageKeyLength)).ToArray();

            foreach (int keyLength in orderKeyLengths)
            {
                string[] columns = GetDecryptColumns(ciphertext, keyLength);
                string sentence = GetOpentext(columns).Take(minSentenceLength);
                var lang = Storage.GetLangChar(language);
                DictionaryAttack attack = new DictionaryAttack(lang.Dictionary, lang.SortedDictionary);
                attack.Start(sentence, keyLength);
            }

            return new List<string>() { "abc" };
        }
예제 #19
0
        /// <summary>
        /// Vrátí pole klíčů, které jsou možnými klíči dané šifry
        /// </summary>
        /// <param name="packet">Informace o šifrovém textu</param>
        /// <returns>Pole klíčů</returns>
        private char[] GetTriangle(string ciphertext, bool orderByDescending, Storage.Languages language)
        {
            char[] topCiphertextLetters;
            char[] topLanguagesLetters;
            int max = 9;

            if (orderByDescending)
            {
                topCiphertextLetters = Analyse.CharsRelativeOccurrence(ciphertext.ToLower()).OrderByDescending(x => x.Value).Take(max).Select(x => x.Key.ToString().ToLower()[0]).ToArray();
                topLanguagesLetters = Storage.GetLangChar(language).Letters.Where(x => x.Key != " ").OrderByDescending(x => x.Value).Take(3).Select(x => x.Key.ToLower()[0]).ToArray();
            }
            else
            {
                topCiphertextLetters = Analyse.CharsRelativeOccurrence(ciphertext.ToLower()).OrderBy(x => x.Value).Take(max).Select(x => x.Key.ToString().ToLower()[0]).ToArray();
                topLanguagesLetters = Storage.GetLangChar(language).Letters.Where(x => x.Key != " ").OrderBy(x => x.Value).Take(3).Select(x => x.Key.ToLower()[0]).ToArray();
            }

            List<char[]> triples = FindEquivalentTriple(topLanguagesLetters, topCiphertextLetters);

            if (triples.Count == 0)
                throw new Exceptions.MatchNotFound();

            return GetKeysFromTriples(topLanguagesLetters[0], triples);
        }
예제 #20
0
        /// <summary>
        /// Provede trojúhelníkový útok na šifru
        /// </summary>
        /// <param name="packet"></param>
        /// <returns></returns>
        public List<string> TriangleAttack(string ciphertext, Storage.Languages language)
        {
            bool modern = true;

            if (modern)
            {
                ciphertext = Analyse.NormalizeText(ciphertext, Analyse.TextTypes.WithoutSpacesLower);
                int polygonSize = 3;
                int complementSize = 10;
                var topLetters = Storage.GetLangChar(language).Letters.OrderByDescending(x => x.Value).Take(polygonSize).Select(x => x.Key[0]).ToArray();
                var bottomLetters = Storage.GetLangChar(language).Letters.OrderBy(x => x.Value).Take(polygonSize).Select(x => x.Key[0]).ToArray();
                var letters = TextAnalysis.GetOccurrence(ciphertext, 1);
                var topTextLetters = letters.OrderByDescending(x => x.Value).Take(complementSize).Select(x => x.Key[0]).ToArray();
                var bottomTextLetters = letters.OrderBy(x => x.Value).Take(complementSize).Select(x => x.Key[0]).ToArray();

                var keysTop = GetPolygonKeys(topTextLetters, topLetters, complementSize);
                var keysBottom = GetPolygonKeys(bottomTextLetters, bottomLetters, complementSize);

                if (keysTop.Length == 0)
                    throw new Exceptions.MatchNotFound();

                var interKeys = keysBottom.Intersect(keysTop).ToList();

                if (interKeys.Count > 0)
                {
                    return interKeys.Select(x => x.ToString()).ToList();
                }
                else
                {
                    var unionKeys = keysBottom.Union(keysTop).Select(x => x.ToString()).ToList();
                    if (unionKeys.Count > 0)
                    {
                        return unionKeys;
                    }
                    else
                    {
                        throw new Exceptions.MatchNotFound();
                    }
                }
            }
            else
            {

                char[] keysTop = GetTriangle(ciphertext, true, language);
                char[] keysLess = GetTriangle(ciphertext, false, language);

                char[] universalKeys = keysLess.Intersect(keysTop).ToArray();
                string key;

                if (universalKeys.Length == 1)
                {
                    key = universalKeys[0].ToString();
                    return new List<string>() { key };
                }
                else
                {
                    char[] unionsKeys = keysLess.Union(keysTop).ToArray();
                    if (unionsKeys.Length != 0)
                    {
                        key = unionsKeys[0].ToString();
                        return new List<string>() { key };
                    }
                }

                throw new Exceptions.MatchNotFound();
            }
        }