aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarcinzelent <zelent.marcin@gmail.com>2018-03-17 15:33:00 +0100
committermarcinzelent <zelent.marcin@gmail.com>2018-03-17 15:33:00 +0100
commitf68bb1864b40c69d12b44db5aa33125aef39e150 (patch)
treebb11f3714a2aa99708f5cca2feec3ff68d3e5b88 /DistributedPasswordCracker.Client/Cracker.cs
parent7e2a8dbd051b94115672cf22cc66ef09ba8376ca (diff)
Restructuring
Diffstat (limited to 'DistributedPasswordCracker.Client/Cracker.cs')
-rw-r--r--DistributedPasswordCracker.Client/Cracker.cs164
1 files changed, 164 insertions, 0 deletions
diff --git a/DistributedPasswordCracker.Client/Cracker.cs b/DistributedPasswordCracker.Client/Cracker.cs
new file mode 100644
index 0000000..9363cc2
--- /dev/null
+++ b/DistributedPasswordCracker.Client/Cracker.cs
@@ -0,0 +1,164 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Security.Cryptography;
+using DistributedPasswordCracker.Client.Models;
+using DistributedPasswordCracker.Client.Utilities;
+
+namespace DistributedPasswordCracker.Client
+{
+ public class Cracking
+ {
+ /// <summary>
+ /// The algorithm used for encryption.
+ /// Must be exactly the same algorithm that was used to encrypt the passwords in the password file
+ /// </summary>
+ private readonly HashAlgorithm _messageDigest;
+
+ public Cracking()
+ {
+ _messageDigest = new SHA1CryptoServiceProvider();
+ //_messageDigest = new MD5CryptoServiceProvider();
+ // seems to be same speed
+ }
+
+ /// <summary>
+ /// Runs the password cracking algorithm
+ /// </summary>
+ public List<UserInfoClearText> RunCracking(string [] dictionary)
+ {
+ Stopwatch stopwatch = Stopwatch.StartNew();
+
+ List<UserInfo> userInfos =
+ PasswordFileHandler.ReadPasswordFile("passwords.txt");
+ Console.WriteLine("passwd opeend");
+
+ List<UserInfoClearText> result = new List<UserInfoClearText>();
+
+ for(int i = 0; i < dictionary.Length; i++)
+ {
+ String dictionaryEntry = dictionary[i];
+ IEnumerable<UserInfoClearText> partialResult = CheckWordWithVariations(dictionaryEntry, userInfos);
+ result.AddRange(partialResult);
+ }
+
+ stopwatch.Stop();
+ Console.WriteLine(string.Join(", ", result));
+ Console.WriteLine("Out of {0} password {1} was found ", userInfos.Count, result.Count);
+ Console.WriteLine();
+ Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);
+
+ return result;
+ }
+
+ /// <summary>
+ /// Generates a lot of variations, encrypts each of the and compares it to all entries in the password file
+ /// </summary>
+ /// <param name="dictionaryEntry">A single word from the dictionary</param>
+ /// <param name="userInfos">List of (username, encrypted password) pairs from the password file</param>
+ /// <returns>A list of (username, readable password) pairs. The list might be empty</returns>
+ private IEnumerable<UserInfoClearText> CheckWordWithVariations(String dictionaryEntry, List<UserInfo> userInfos)
+ {
+ List<UserInfoClearText> result = new List<UserInfoClearText>(); //might be empty
+
+ String possiblePassword = dictionaryEntry;
+ IEnumerable<UserInfoClearText> partialResult = CheckSingleWord(userInfos, possiblePassword);
+ result.AddRange(partialResult);
+
+ String possiblePasswordUpperCase = dictionaryEntry.ToUpper();
+ IEnumerable<UserInfoClearText> partialResultUpperCase = CheckSingleWord(userInfos, possiblePasswordUpperCase);
+ result.AddRange(partialResultUpperCase);
+
+ String possiblePasswordCapitalized = StringUtilities.Capitalize(dictionaryEntry);
+ IEnumerable<UserInfoClearText> partialResultCapitalized = CheckSingleWord(userInfos, possiblePasswordCapitalized);
+ result.AddRange(partialResultCapitalized);
+
+ String possiblePasswordReverse = StringUtilities.Reverse(dictionaryEntry);
+ IEnumerable<UserInfoClearText> partialResultReverse = CheckSingleWord(userInfos, possiblePasswordReverse);
+ result.AddRange(partialResultReverse);
+
+ for (int i = 0; i < 100; i++)
+ {
+ String possiblePasswordEndDigit = dictionaryEntry + i;
+ IEnumerable<UserInfoClearText> partialResultEndDigit = CheckSingleWord(userInfos, possiblePasswordEndDigit);
+ result.AddRange(partialResultEndDigit);
+ }
+
+ for (int i = 0; i < 100; i++)
+ {
+ String possiblePasswordStartDigit = i + dictionaryEntry;
+ IEnumerable<UserInfoClearText> partialResultStartDigit = CheckSingleWord(userInfos, possiblePasswordStartDigit);
+ result.AddRange(partialResultStartDigit);
+ }
+
+ for (int i = 0; i < 10; i++)
+ {
+ for (int j = 0; j < 10; j++)
+ {
+ String possiblePasswordStartEndDigit = i + dictionaryEntry + j;
+ IEnumerable<UserInfoClearText> partialResultStartEndDigit = CheckSingleWord(userInfos, possiblePasswordStartEndDigit);
+ result.AddRange(partialResultStartEndDigit);
+ }
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Checks a single word (or rather a variation of a word): Encrypts and compares to all entries in the password file
+ /// </summary>
+ /// <param name="userInfos"></param>
+ /// <param name="possiblePassword">List of (username, encrypted password) pairs from the password file</param>
+ /// <returns>A list of (username, readable password) pairs. The list might be empty</returns>
+ private IEnumerable<UserInfoClearText> CheckSingleWord(IEnumerable<UserInfo> userInfos, String possiblePassword)
+ {
+ char[] charArray = possiblePassword.ToCharArray();
+ byte[] passwordAsBytes = Array.ConvertAll(charArray, PasswordFileHandler.GetConverter());
+
+ byte[] encryptedPassword = _messageDigest.ComputeHash(passwordAsBytes);
+ //string encryptedPasswordBase64 = System.Convert.ToBase64String(encryptedPassword);
+
+ List<UserInfoClearText> results = new List<UserInfoClearText>();
+
+ foreach (UserInfo userInfo in userInfos)
+ {
+ if (CompareBytes(userInfo.EntryptedPassword, encryptedPassword)) //compares byte arrays
+ {
+ results.Add(new UserInfoClearText(userInfo.Username, possiblePassword));
+ Console.WriteLine(userInfo.Username + " " + possiblePassword);
+ }
+ }
+ return results;
+ }
+
+ /// <summary>
+ /// Compares to byte arrays. Encrypted words are byte arrays
+ /// </summary>
+ /// <param name="firstArray"></param>
+ /// <param name="secondArray"></param>
+ /// <returns></returns>
+ private static bool CompareBytes(IList<byte> firstArray, IList<byte> secondArray)
+ {
+ //if (secondArray == null)
+ //{
+ // throw new ArgumentNullException("firstArray");
+ //}
+ //if (secondArray == null)
+ //{
+ // throw new ArgumentNullException("secondArray");
+ //}
+ if (firstArray.Count != secondArray.Count)
+ {
+ return false;
+ }
+ for (int i = 0; i < firstArray.Count; i++)
+ {
+ if (firstArray[i] != secondArray[i])
+ return false;
+ }
+ return true;
+ }
+
+ }
+} \ No newline at end of file