Crack MD5

di il
4 risposte

Crack MD5

Buonasera, devo fare un compito per un esame di java e devo riuscire a crackare nel minor tempo possibile le password in MD5. Qualcuno riesce in 2 secondi a crackare parole di lunghezza 5 mentre io non riesco. Sto usando il forkjoinpool e il divide et impera. Le disposizioni con ripetizioni le calcolo usando una numerazione fino a 36 (l'alfabeto dato è formato da 26 lettere + i numeri). Quindi a 0 corrisponde A, a 1 B e a 36 9 e così via. Quindi ricorsivamente creo thread sempre più piccoli e su questi in ciclo mi trovo la parola e la crypto e la confronto con l'MD5 dato. Esistono metodi più veloci per procedere? Grazie!

4 Risposte

  • Re: Crack MD5

    Io, per curiosità, ho voluto fare una prova veloce e buttata giù al volo per capire quanto tempo ci impiega a calcolare il MD5 di tutte le 36^5 combinazioni, senza fare nulla in ambito multi-threading.
    import java.security.MessageDigest;
    
    public class Md5Combinations {
        private static final char[] alfabeto = {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
            'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
        };
    
        public static void main(String[] args) {
            try {
                MessageDigest md5 = MessageDigest.getInstance("MD5");
    
                int count = 0;
                byte[] buf = new byte[5];
                long t1 = System.currentTimeMillis();
    
                for (int i1 = 0; i1 < alfabeto.length; i1++) {
                    for (int i2 = 0; i2 < alfabeto.length; i2++) {
                        for (int i3 = 0; i3 < alfabeto.length; i3++) {
                            for (int i4 = 0; i4 < alfabeto.length; i4++) {
                                for (int i5 = 0; i5 < alfabeto.length; i5++) {
                                    buf[0] = (byte) alfabeto[i1];
                                    buf[1] = (byte) alfabeto[i2];
                                    buf[2] = (byte) alfabeto[i3];
                                    buf[3] = (byte) alfabeto[i4];
                                    buf[4] = (byte) alfabeto[i5];
                                    
                                    md5.reset();
                                    byte[] md5hash = md5.digest(buf);
                                    count++;
                                }
                            }
                        }
                    }
                }
    
                long t2 = System.currentTimeMillis();
    
                System.out.println(count + " combinazioni in " + (t2-t1) + " ms.");
            } catch (Exception e) {
                System.err.println(e);
            }
        }
    }
    Il risultato a me fornito è:

    60466176 combinazioni in 14750 ms.

    Ovvero 14 secondi e rotti per tutte le combinazioni.

    C'è da tenere presente che:
    a) Il codice è ovviamente mono thread, come è evidente dal codice.
    b) Lo sto provando sul notebook di ufficio che non ha certo un processore di quelli particolarmente "svegli" (è "solo" un 2.4GHz).

    Se introducessi il multi-threading per sfruttare più core (e magari su un processore molto più sveglio!), chiaramente il tempo scenderebbe abbastanza.
  • Re: Crack MD5

    Non so come ringraziarti! Mi hai fatto scoprire il problema. In poche parole, con il mio codice, per trovare la parola giusta devo dare in input alla funzione un MD5, prendere ogni combinazione trovata, convertirla in MD5, fare il confronto e vedere se sono uguali. Tramite un profiler ho notato che la funzione più pesante era proprio quella che convertiva in MD5. Il tuo codice si ferma a
    byte[] md5hash = md5.digest(buf);
    mentre io ho necessità di trovare MD5 e fare come nel codice fornito dalla nostra professoressa:
    public class MD5HashingExample {
    public static void main(String[] args) throws Exception {
    String password = "123456";
    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(password.getBytes());
    byte byteData[] = md.digest();
    // convert the byte to hex format
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < byteData.length; i++) {
    sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
    }
    System.out.println("Digest(in hex format):: " + sb.toString());
    }
    }
    Quindi, applicando
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < byteData.length; i++) {
    sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
    }
    al tuo codice, dai 14 secondi passo a oltre i 60. Quindi, questo ciclo, che mi genera la stringa MD5, mi aumenta di molto la computazione. C'è un modo per non dover fare per forza questo ciclo? GRAZIE MILLE!!!!!!!!!
  • Re: Crack MD5

    KILLERIX ha scritto:


    Quindi, questo ciclo, che mi genera la stringa MD5, mi aumenta di molto la computazione. C'è un modo per non dover fare per forza questo ciclo?
    Innanzitutto nel mio codice non ho voluto subito provare a fare la ricerca .... volevo solo giusto verificare le tempistiche basilari.

    Lo sbaglio concettuale del tuo codice è che tu per ogni digest (ovvero i 16 byte "crudi", binari, del hash md5) vai a formattare una stringa e probabilmente su questa vai a fare il confronto per trovare quello dato in input.
    Questo, cioè la formattazione, è un lavoro abbastanza grosso dal punto di vista computazionale e sicuramente fa lievitare di parecchio i tempi.

    Se parti con un hash in stringa da cercare es. "8f118a7ad194b63358e9c3a576b75c92" dovresti parsarlo/validarlo in qualche modo (non c'è un metodo già fatto nel framework per questo) ed ottenere un byte[] di 16 byte.

    Quindi confronti byte[] ... non stringhe. Per confrontare due byte[] o fai un ciclo apposito oppure usi il equals(byte[] a, byte[] a2) di java.util.Arrays (nota che equals degli oggetti non basta, per gli array si basa solo sulla identità)
  • Re: Crack MD5

    Sei un mito! Grazie mille! Avendo avuto quel metodo dalla professoressa non pensavo fosse così pesante eseguirlo 36^n volte. Ora tramite la classe di java HexBin mi trasformo un md5 in byte[] e così posso confrontarlo subito con il digest senza fare trasformazioni inutili con stringhe e così mi aumenta di un solo secondo il codice che mi hai dato. Ora implemento il ForkJoinPool e dovrebbe andare! GRAZIE MILLE!!!!!!!
Devi accedere o registrarti per scrivere nel forum
4 risposte