overwraith Posted October 3, 2014 Share Posted October 3, 2014 Am working on a password/passphrase cracker, and I thought I would share a neat little snippet I made. I am sure it would depleat memory at higher volumes, but I am working on a distributed, managed program, so I am not too worried about it. Is coded in C#. TestPassword is a delegate, so can pass different tests to this method, are not hard coded. If you have any better code would love to see snippets. //this method will depleat memory for larger wordlists, should re-design later public String dictionaryCrack(TestPassword test) { String password = ""; Parallel.ForEach<String>(File.ReadAllLines(fname), (String str, ParallelLoopState state) => { if (test.Invoke(str, this)) { //record the password password = str; //break out of the loop state.Break(); } }); return password; }//end method Quote Link to comment Share on other sites More sharing options...
cooper Posted October 3, 2014 Share Posted October 3, 2014 (edited) Instead of "ReadAllLines" you should use "ReadLines". The difference between the two is that the first one first reads all the lines from the file into memory and only then returns the enumeration. The second returns an enumeration backed by the file immediately and requesting the next element from the enumeration will result in the reading of the next line in the file. In other words, no buffering. Particularly with larger files this streaming approach is far more efficient. Aside from that little thing which could be considered a memory depletion problem I don't see where you're potentially going overboard with memory use. You could make the method more generic. public String parallelFindLineInFile(String filename, Func<String,Boolean> findFunction) { String result = null; Parallel.ForEach<String>(File.ReadLines(filename), (String str, ParallelLoopState state) => { if (findFunction(str)) { result = str; state.Break(); } }); return result; } Not sure if this even compiles - I don't typically work in C#, but I'm sure you get the idea. Edited October 3, 2014 by Cooper Quote Link to comment Share on other sites More sharing options...
overwraith Posted October 3, 2014 Author Share Posted October 3, 2014 (edited) Interesting thoughts. If anybody else wants to post, other languages are welcome too. Printing out the readlines vs readalllines MSDN page, good call. These would be the functions that would be given as delegates to the password cracker: /*Author: overwraith*/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; namespace DistributedWordList { public static class HashTests { public static bool TestSHA1Cng(String str, DistributedWordList wordlist) { HashAlgorithm hash = SHA1Cng.Create(); System.Text.UTF8Encoding enc2 = new System.Text.UTF8Encoding(); byte[] bytes = enc2.GetBytes(str); byte[] matchHash = hash.ComputeHash(bytes); //test for hash equility bool match = true; for (int i = 0; i < matchHash.Length; i++) { if (wordlist.hash[i] != matchHash[i]) { match = false; break; } }//end loop return match; }//end method public static bool TestMD5(String str, DistributedWordList wordlist) { HashAlgorithm hash = MD5.Create(); System.Text.UTF8Encoding enc2 = new System.Text.UTF8Encoding(); byte[] bytes = enc2.GetBytes(str); byte[] matchHash = hash.ComputeHash(bytes); //test for hash equility bool match = true; for (int i = 0; i < matchHash.Length; i++) { if (wordlist.hash[i] != matchHash[i]) { match = false; break; } }//end loop return match; }//end method public static bool TestRIPEMD160Managed(String str, DistributedWordList wordlist) { HashAlgorithm hash = RIPEMD160Managed.Create(); System.Text.UTF8Encoding enc2 = new System.Text.UTF8Encoding(); byte[] bytes = enc2.GetBytes(str); byte[] matchHash = hash.ComputeHash(bytes); //test for hash equility bool match = true; for (int i = 0; i < matchHash.Length; i++) { if (wordlist.hash[i] != matchHash[i]) { match = false; break; } }//end loop return match; }//end method public static bool TestSHA256(String str, DistributedWordList wordlist) { HashAlgorithm hash = SHA256.Create(); System.Text.UTF8Encoding enc2 = new System.Text.UTF8Encoding(); byte[] bytes = enc2.GetBytes(str); byte[] matchHash = hash.ComputeHash(bytes); //test for hash equility bool match = true; for (int i = 0; i < matchHash.Length; i++) { if (wordlist.hash[i] != matchHash[i]) { match = false; break; } }//end loop return match; }//end method public static bool TestSHA384(String str, DistributedWordList wordlist) { HashAlgorithm hash = SHA384.Create(); System.Text.UTF8Encoding enc2 = new System.Text.UTF8Encoding(); byte[] bytes = enc2.GetBytes(str); byte[] matchHash = hash.ComputeHash(bytes); //test for hash equility bool match = true; for (int i = 0; i < matchHash.Length; i++) { if (wordlist.hash[i] != matchHash[i]) { match = false; break; } }//end loop return match; }//end method public static bool TestSHA512(String str, DistributedWordList wordlist) { HashAlgorithm hash = SHA512.Create(); System.Text.UTF8Encoding enc2 = new System.Text.UTF8Encoding(); byte[] bytes = enc2.GetBytes(str); byte[] matchHash = hash.ComputeHash(bytes); //test for hash equility bool match = true; for (int i = 0; i < matchHash.Length; i++) { if (wordlist.hash[i] != matchHash[i]) { match = false; break; } }//end loop return match; }//end method public static bool TestSha1(String str, DistributedWordList wordlist) { HashAlgorithm hash = SHA1.Create(); System.Text.UTF8Encoding enc2 = new System.Text.UTF8Encoding(); byte[] bytes = enc2.GetBytes(str); byte[] matchHash = hash.ComputeHash(bytes); //test for hash equility bool match = true; for (int i = 0; i < matchHash.Length; i++) { if (wordlist.hash[i] != matchHash[i]) { match = false; break; } }//end loop return match; }//end method }//end class }//end namespace Edited October 3, 2014 by overwraith Quote Link to comment Share on other sites More sharing options...
cooper Posted October 3, 2014 Share Posted October 3, 2014 (edited) Clearly you need to use this utility method, stolen anabashedly from StackOverflow: static bool ArraysEqual<T>(T[] a1, T[] a2) { if (ReferenceEquals(a1,a2)) return true; if (a1 == null || a2 == null) return false; if (a1.Length != a2.Length) return false; EqualityComparer<T> comparer = EqualityComparer<T>.Default; for (int i = 0; i < a1.Length; i++) { if (!comparer.Equals(a1[i], a2[i])) return false; } return true; } And with my own little addition: private static bool TestHash(HashAlgorithm hash, String str, DistributedWordList wordlist) { System.Text.UTF8Encoding enc2 = new System.Text.UTF8Encoding(); // This should be a single global which gets reused a HECK of a lot. return ArraysEqual( enc2.GetBytes(str), hash.ComputeHash(bytes) ); }//end method That would allow any of these methods you have to be reduced to just this: public static bool TestSha1(String str, DistributedWordList wordlist) { return TestHash(SHA1.Create(), str, wordlist); }//end method Edited October 3, 2014 by Cooper Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.