[RESOLVIDO]Laço de repetição, igualando uma variável a um dicionário

13 respostas
G

Bem eu sou iniciante em programação, muito iniciante, estou no primeiro semestre de ADS. Tenho um programa para fazer. A ideia do programa é quebrar hashs. qui vai meu código.

package testemd5;

import br.com.senacrs.util.MD5;

public class TesteMD5 {

    @SuppressWarnings("empty-statement")
    public static void main(String[] args) {
        char dictAll[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', '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', 'A', 'B', 'C', 'D',
            'F', 'G', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
            'W', 'V', 'X', 'Y', 'Z', '!', '@', '#', '$', '%', '&', '*', '(', ')', '_', '-',
            '+', '=', '[', ']', '{', '}', '?', '/', '|', '>', '<'};
        String dicthash[] = {"60bb1f9914c26fb929b724398e5d2f66", "81dc9bdb52d04dc20036dbd8313ed055",
            "e2fc714c4727ee9395f324cd2e7f331f", "a4ab812db5e84ec4280a2067a0e009a8", "2b8160cf839671250fc0dabac7cc1d4e",
            "a9cec9eeae78b260c010bc84b79a2330", "813c9e77c864c7cfc8b2ad9472c1dde6", "31be29a3d43701323c50de65d71af097",
            "0a76d8749da8f67c37b6a3678d45ce9a", "01499346f9267b51e35095365aed4f15", "f38fef4c0e4988792723c29a0bd3ca98",
            "229ae56bf5c7e60a1d0db30b423e6af6", "4998654b7d255461cd5110d5dcbac05b", "6af5f30627d3823099c2541d0b9326fc",
            "5c55036d0b9dadec219f65c9d8d420c1", "a284236e525bff59c8956266df0ac1ea", "ca4abb07a2e12b9008c49953db2d0c0d",
            "153ddfb15ae1e37b7cf004b201c3e3fd", "9cda986cec137d423863c2f9fca7c543", "3c2effe3f1157e5038b1dd0687d15957",
            "2f4278d6d27c99dc212f23093ae9ac8e", "864a77ce17937bf629637a939b69da64", "9b82b6de580184657e6d95c4cfb2f337",
            "e68d3c6431bf1e25eced5d26c301f68d", "e9510081ac30ffa83f10b68cde1cac07", "ff434d71061293390990711649b9dfd9",
            "9de37a0627c25684fdd519ca84073e34", "b73fdaa1fb7669da760b49600c45d9be", "8343f6af1f2313770bea1954bbf3b3c6",
            "3a4d92a1200aad406ac50377c7d863aa"};

        System.out.println("Seja Bem Vindo!");

        char palavra2[] = new char[4];

        long timeI = System.currentTimeMillis();
        for (int f = 0; f < dictAll.length; f++) {
            palavra2[3] = dictAll[f];
            for (int b = 0; b < dictAll.length; b++) {
                palavra2[2] = dictAll[b];
                for (int j = 0; j < dictAll.length; j++) {
                    palavra2[0] = dictAll[j];
                    for (int i = 0; i < dictAll.length; i++) {
                        palavra2[1] = dictAll[i];
                        String hash = MD5.gerarMD5(String.valueOf(palavra2));
                        System.out.println("VALOR -> " + String.valueOf(palavra2));
                        System.out.println("HASH: " + hash);

                        for (int h = 0; h < dicthash.length; h++) {
                            if (hash.equalsIgnoreCase (h)) {
                                long total_quebra = ((System.currentTimeMillis() - timeI) / 1000);
                                System.out.println("SENHA QUEBRADA! EM: " + total_quebra + " segundos");
                                System.out.println("SENHA: " + String.valueOf(palavra2));
                                System.out.println("HASH: " + hash);


                            }
                        }
                    }
                }
            }
            long timeF = System.currentTimeMillis();
            long total = timeI - timeF;
            System.out.println("Tempo Final: " + total);

        }
    }

O que acontece eu quero que o programa faça um laço de repetição, igualando todas as hashs do dicionario “dicthash” a variável hash. Mas como vcs podem ver há um erro aí.
Meu if não dá certo. Alguém pode me ajudar com isso?’
Desde já agradeço.

13 Respostas

igrsantos

Amigo se possível, postar seu método de gerar MD5, para podermos verificar o ocorrido !

G
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.senacrs.util;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Angelo
 */
public class MD5 {

    public static String gerarMD5(String senha) {
        MessageDigest md;
        String crypto;
        try {
            /**
             * Aqui dizemos qual o tipo de hash vamos trabalhar, poderia ser
             * outro, como SHA.
             */            
            md = MessageDigest.getInstance("MD5");
            /**
             * Aqui trablamos com BigInteger para suportar uma grande quantia
             * de caracteres.
             */             
            BigInteger hash = new BigInteger(1, md.digest(senha.getBytes()));
            
            /**
             * Transforma o hash em String.
             */
            crypto = hash.toString(16);
            
            /**
             * Verifica de um 0 a esquerda não foi ignorado, caso positivo,
             * readiciona.
             */
            if (crypto.length() % 2 != 0) {
                crypto = "0" + crypto;
            }
            
            /**
             * Retorna a palavra criptografada.
             */
            return crypto;
        } catch (NoSuchAlgorithmException ex) {
            System.out.println("Um erro ocorreu ao tentar gerar o Hash da palavra");
            return "ERRO";
        }
        

        
    }
}

Esse código foi disponibilizado pelo professor. Não foi ensinado ainda em aula, devo usar este código e fazer o resto sozinho.

igrsantos

Beleza muito bem, o seu código está muito bacana.

Já descobrir o seu problema, está exatamente nessa parte do código.

for (int h = 0; h < dicthash.length; h++) { if (hash.equalsIgnoreCase(h)) { long total_quebra = ((System.currentTimeMillis() - timeI) / 1000); System.out.println("SENHA QUEBRADA! EM: " + total_quebra + " segundos"); System.out.println("SENHA: " + String.valueOf(palavra2)); System.out.println("HASH: " + hash); } }

onde você compara no hash o inteiro h e não a hash do array.
utilize assim:

for (int h = 0; h < dicthash.length; h++) { if (hash.equalsIgnoreCase(dicthash[h])) { long total_quebra = ((System.currentTimeMillis() - timeI) / 1000); System.out.println("SENHA QUEBRADA! EM: " + total_quebra + " segundos"); System.out.println("SENHA: " + String.valueOf(palavra2)); System.out.println("HASH: " + hash); } }

você pode melhora-lo também imprimindo só o resultado, fazendo com que leve menos tempo pra terminar o algoritmo,
e pode verificar se já quebrou todas as senhas, pois mesmo quando tiver quebrado todas as senhas,
seu algoritmo ficara executando até o fim das combinações !

G

Humm belzeza, vou tentar aqui. Muito Obrigado igrsantos.

G

Ah outra pergunta… Como faz para o esse programa de quebrar hash usar todos os núcleos no meu CPU?

igrsantos

Amigo, não tenho muita noção.

Mas para ter uma maior eficiência, você pode utilizar de Thread’s.

Agora para utilizar todos os núcleos do seu computador, você vai ter que esperar o Java 8
que vai vim com muitas vantagens, que possuem as linguagens como Python e Ruby.

Como exemplo as funções lambda.

G

Pode me dar uma ajuda com essas Threads?

igrsantos

Posso sim cara, uma dica é você primeiro separar seu código de forma
que você possa utiliza-lo paralelamente.

Rode uma parte em cada Thread, dê uma lida sobre thread java.

Qualquer coisa chama aqui !

igrsantos

grifon, implementei um código bem básico com threads em cima do teu algoritmo,
e não me apeguei muito a boa prática não, só pra você ver como é que funciona mais
ou menos.

Exemplo com 2 Thread's:
public class TesteMD5 {
    static char dictAll[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', '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', 'A', 'B', 'C', 'D',
        'F', 'G', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
        'W', 'V', 'X', 'Y', 'Z', '!', '@', '#', '$', '%', '&', '*', '(', ')', '_', '-',
        '+', '=', '[', ']', '{', '}', '?', '/', '|', '>', '<'};
    
    static String dicthash[] = {"60bb1f9914c26fb929b724398e5d2f66", "81dc9bdb52d04dc20036dbd8313ed055",
        "e2fc714c4727ee9395f324cd2e7f331f", "a4ab812db5e84ec4280a2067a0e009a8",    "2b8160cf839671250fc0dabac7cc1d4e",
        "a9cec9eeae78b260c010bc84b79a2330", "813c9e77c864c7cfc8b2ad9472c1dde6", "31be29a3d43701323c50de65d71af097",
        "0a76d8749da8f67c37b6a3678d45ce9a", "01499346f9267b51e35095365aed4f15", "f38fef4c0e4988792723c29a0bd3ca98",
        "229ae56bf5c7e60a1d0db30b423e6af6", "4998654b7d255461cd5110d5dcbac05b", "6af5f30627d3823099c2541d0b9326fc",
        "5c55036d0b9dadec219f65c9d8d420c1", "a284236e525bff59c8956266df0ac1ea", "ca4abb07a2e12b9008c49953db2d0c0d",
        "153ddfb15ae1e37b7cf004b201c3e3fd", "9cda986cec137d423863c2f9fca7c543", "3c2effe3f1157e5038b1dd0687d15957",
        "2f4278d6d27c99dc212f23093ae9ac8e", "864a77ce17937bf629637a939b69da64", "9b82b6de580184657e6d95c4cfb2f337",
        "e68d3c6431bf1e25eced5d26c301f68d", "e9510081ac30ffa83f10b68cde1cac07", "ff434d71061293390990711649b9dfd9",
        "9de37a0627c25684fdd519ca84073e34", "b73fdaa1fb7669da760b49600c45d9be", "8343f6af1f2313770bea1954bbf3b3c6",
        "3a4d92a1200aad406ac50377c7d863aa"};

    static int senhasEncontradas;
    
    @SuppressWarnings("empty-statement")
    public static void main(String[] args) {

        System.out.println("Seja Bem Vindo!");
        senhasEncontradas = 0;
        // executando primeira thread, que realiza o processo do final pro meio dos hashs
        threadExecucao1.start();
        // executando segunda thread, que realiza o processo do inicio pro meio dos hashs
        threadExecucao2.start();    
    }
    
    static Thread threadExecucao1 = new Thread(new Runnable() {
        @Override
        public void run() {
            char palavra2[] = new char[4];

            long timeI = System.currentTimeMillis();
            for (int f = 0; f < dictAll.length; f++) {
                palavra2[3] = dictAll[f];
                for (int b = 0; b < dictAll.length; b++) {
                    palavra2[2] = dictAll[b];
                    for (int j = 0; j < dictAll.length; j++) {
                        palavra2[0] = dictAll[j];
                        for (int i = 0; i < dictAll.length; i++) {
                            palavra2[1] = dictAll[i];
                            String hash = Utils.encryptPassword(String.valueOf(palavra2));

                            for (int h = dicthash.length - 1; h > dicthash.length / 2; h--) {
                                if (hash.equalsIgnoreCase(dicthash[h])) {
                                    senhasEncontradas ++;
                                    long total_quebra = ((System.currentTimeMillis() - timeI) / 1000);
                                    System.out.println("SENHA QUEBRADA NA THREAD 1 EM: " + total_quebra + " segundos");
                                    System.out.println("SENHA: " + String.valueOf(palavra2));
                                    System.out.println("HASH: " + hash);
                                    System.out.println("Senhas encontradas até o momento: " + senhasEncontradas);
                                }
                            }
                        }
                    }
                }
            }
        }
    });
    
    static Thread threadExecucao2 = new Thread(new Runnable() {
        @Override
        public void run() {
            char palavra2[] = new char[4];

            long timeI = System.currentTimeMillis();
            for (int f = 0; f < dictAll.length; f++) {
                palavra2[3] = dictAll[f];
                for (int b = 0; b < dictAll.length; b++) {
                    palavra2[2] = dictAll[b];
                    for (int j = 0; j < dictAll.length; j++) {
                        palavra2[0] = dictAll[j];
                        for (int i = 0; i < dictAll.length; i++) {
                            palavra2[1] = dictAll[i];
                            String hash = Utils.encryptPassword(String.valueOf(palavra2));

                            for (int h = 0; h < dicthash.length / 2; h++) {
                                if (hash.equalsIgnoreCase(dicthash[h])) {
                                    long total_quebra = ((System.currentTimeMillis() - timeI) / 1000);
                                    senhasEncontradas ++;
                                    System.out.println("SENHA QUEBRADA NA THREAD 2 EM : " + total_quebra + " segundos");
                                    System.out.println("SENHA: " + String.valueOf(palavra2));
                                    System.out.println("HASH: " + hash);
                                    System.out.println("Senhas encontradas até o momento: " + senhasEncontradas);
                                }
                            }
                        }
                    }
                }
            }
        }
    });
}
Analise o código e veja o que tem de diferente, qualquer dúvida estamos ai ;)
E

Aham - mesmo desde o Java 1.1 você pode usar todas as threads.
É só que a partir do Java 5 há algumas comodidades para o uso de encapsulamento de threads (as classes do pacote java.util.concurrent).
Não é necessário usar lambdas (que se mal usadas podem é deixar seu programa mais lento, não mais rápido) nem o pacote fork/join (embora só esteja no JDK a partir do Java 8, o fork/join é uma biblioteca que pode ser instalada separadamente e baixada do site do dr. Doug Lea ).

E

A propósito, leia os seguintes artigos do Ars Technica, e veja como é que os profissionais quebram as senhas MD5:


igrsantos

Obrigado entanglement,

ainda não tenho muita experiência, e escrevi com base no que tenho lido.

Mas muito boa a explicação, vou dar uma pesquisar melhor nesse assunto :slight_smile:

G

Obrigado igrsantos, vou tentar fazer as threads com base no seu código e valew as dicas ae entanglement!

Criado 3 de junho de 2013
Ultima resposta 4 de jun. de 2013
Respostas 13
Participantes 3