Gå til innhold

C#: md5 brute-forcer, dårlig ytelse. pga C# eller meg?


Anbefalte innlegg

Skrevet

lenge siden jeg har drevet noe med C# nå, så tenkte jeg skulle lage en enkel brute-forcer. problemet er ytelsen: jeg får snaut nok 150 000 hash pr. sekund, mens i mer "profesjonelle" brute-force programmer ligger jeg på 2,9 millioner pr sek (det er på en kjerne).

 

funksjonen for å generere hashen ser ganske enkelt slik ut:

 public static string EncodeMD5(string input)
 {
 	byte[] originalBytes;
 	byte[] encodedBytes;
 	MD5 md5;
 	
 	md5 = new MD5CryptoServiceProvider();
 	originalBytes = ASCIIEncoding.Default.GetBytes(input);
 	encodedBytes = md5.ComputeHash(originalBytes);
 	
 	string result = Regex.Replace(BitConverter.ToString(encodedBytes), "-", "");
 	return result.ToLower();
 }

 

og så kaller jeg bare den funksjonen 100 000 ganger i en loop, sammenlikner med en tilfeldig hash hver gang (kun for å teste farten altså):

 	DateTime dt = DateTime.Now;
 	for(int i = 0; i < 100000; i++)
 	{
   // vil selvsagt alltid feile
   if(String.Compare("da8e41b62c755d35ab985e2bef6eb064", 
                     md5.EncodeMD5("Hakon")) == 0)
   	break;
 	}
 	
 	TimeSpan ts = DateTime.Now.Subtract(dt);
 	float speed = (float) ( 100000000 /  ts.Milliseconds );
 	string output = "Det tok " + ts.Milliseconds.ToString() + "ms å kalkulere " +
   "en hash 100 000 ganger. Det vil si at farten var " + 
   speed.ToString() + " hash/sek";
 	
 	MessageBox.Show(output);

 

finnes det bedre måter å gjøre det på? jeg skjønner jo at C# ikke er det beste valget av språk for en slik oppgave, men hadde håpet på hvertfall litt bedre ytelse, mer i nærheten av 1 000 000.

Videoannonse
Annonse
Skrevet

Det tok 29ms å kalkulere en hash 100 000 ganger. Det vil si at farten var 3.448.275 hash/sek

 

 

:)

 

Men, det var fordi du har .Milliseconds, og ikke .TotalMilliseconds.

 

 

Litt optimalisering:

       private static MD5 md5 = new MD5CryptoServiceProvider();
       private static Encoding minEncoding; // Sett denne et eller annet sted i koden til = Encoding.ASCII;
       public static string EncodeMD5(string input)
       {
           byte[] originalBytes = minEncoding.GetBytes(input);
           return md5.ComputeHash(originalBytes);
       }

 

Dessuten kan du la være å konvertere til string, og heller sammenligne byte[].

ASCIIEncoding.Default er det samme som Encoding.Default, og gir ikke nødvendigvis ASCIIEncoding tilbake. Bruk heller Encoding.ASCII;

 

Ved å gjøre dette gikk det over 3x raskere på min maskin. Men fortsatt ikke raskt nok iforhold til hva du ønsket...

Skrevet (endret)

det gikk kanskje 30 % raskere på min maskin, men jeg får bare en merkelig feil når jeg flytter

MD5 md5 = new MD5CryptoServiceProvider();

utenfor metoden.

 

slik ser klassen ut nå:

namespace md5
{
/// <summary>
/// Description of md5.
/// </summary>
public class md5
{
 private static Encoding minEncoding = Encoding.ASCII;
 static byte[] originalBytes;
 
 public static byte[] EncodeMD5(string input)
 {
 	MD5 _md5 = new MD5CryptoServiceProvider();
 	
 	originalBytes = minEncoding.GetBytes(input);
 	return _md5.ComputeHash(originalBytes);
 }
}
}

 

jeg kjører to instanser samtidig ved å bruke delegate.BeginInvoke, men da kjører ikke den første threaden i det hele tatt. den gir da over 10 millioner pr. sek, mens den andre threaden gjør som den skal.

 

EDIT: skjønte ikke stort av linkene dine :blush::whistle:

Endret av hockey500
Skrevet

Hvis du kjører flere instanser så må du enten ha flere instanser av MD5CryptoProvider, eller kjøre lock/monitor.enter på den (og da vil jo kun 1 kjøre om gangen)...

Skrevet
finnes det bedre måter å gjøre det på? jeg skjønner jo at C# ikke er det beste valget av språk for en slik oppgave, men hadde håpet på hvertfall litt bedre ytelse, mer i nærheten av 1 000 000.

8099762[/snapback]

En VM bør vel ligge på linje med et kompilert språk på en slik oppgave, eller kanskje foran mtp at den f.eks. kan inline hele bibliotek-kallet om det skulle være hensiktsmessig.

 

For å finne ut hvordan programmet bruker tiden sin trenger du en profiler. Antar at CLR har noe slikt. ;)

 

Har ett tips som jeg tipper vil øke hastigheten noe; Mener det koster litt å initialisere MD5, så jeg tipper ting vil gå litt raskere om du lager èn tom hash og bare kloner denne for hver iterasjon.

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...