Task

Find, through brute force, the five-letter passwords corresponding with the following SHA-256 hashes:

1. 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad
2. 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
3. 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f

Your program should naively iterate through all possible passwords consisting only of five lower-case ASCII English letters. It should use concurrent or parallel processing, if your language supports that feature. You may calculate SHA-256 hashes by calling a library or through a custom implementation. Print each matching password, along with its SHA-256 hash.

Related task: SHA-256

import javax.xml.bind.DatatypeConverter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
/**
 * "Main Program" that does the parallel processing
 */
public class ParallelBruteForce {
 
    public static void main(String[] args) throws NoSuchAlgorithmException {
 
        //the hashes to be cracked
        String[] hashes = {"1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad",
                "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
                "74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"};
 
        //An ExecutorService is a high-level parallel programming facility, that can execute a number of tasks
        //the FixedThreadPool is an ExecutorService that uses a configurable number of parallel threads
        ExecutorService executorService = Executors.newFixedThreadPool(3);
 
        //Submit one Task per hash to the thread po
        for (String hash : hashes) {
            executorService.submit(new Forcer(hash));
        }
 
        //An ExecutorSerice must be shut down properly (this also causes the program to await termination of
        // all pending tasks in the thread pool)
        executorService.shutdown();
    }
}
 
/**
 * The Class that contains the actual brute-forcing task.
 * <p>
 * It implements the build-in Interface "Runnable", so it can be run on a Thread or a Thread-Execution-Facility
 * (such as an ExecutorService).
 */
class Forcer implements Runnable {
 
    private static final int LENGTH = 5;
 
    //These will sore the hash to be cracked in both bytes (required for comparison) and String representation
    // (required for output)
    private final byte[] crackMe;
    private final String crackMeString;
 
    //The MessageDigest does the SHA-256 caclulation. Note that this may throw a NoSuchAlgorithmException when there
    // is no SHA-256 implementation in the local standard libraries (but that algorithm is mandatory, so this code
    // probably will never throw that Excpetion
    private final MessageDigest digest = MessageDigest.getInstance("SHA-256");
 
    public Forcer(String crackMe) throws NoSuchAlgorithmException {
        this.crackMeString = crackMe;
        this.crackMe = DatatypeConverter.parseHexBinary(crackMe);
    }
 
    @Override
    public void run() {
 
        String match = "";
 
        //all loops use this array for their counters. This is very dirty and should never be done in production!
        char[] chars = new char[LENGTH];
 
        //used for short-stopping when a match is found - one could abuse the match-variable for this, but this is
        // much clearer
        boolean done = false;
 
        for (chars[0] = 'a'; chars[0] <= 'z' && !done; chars[0]++) {
            for (chars[1] = 'a'; chars[1] <= 'z' && !done; chars[1]++) {
                for (chars[2] = 'a'; chars[2] <= 'z' && !done; chars[2]++) {
                    for (chars[3] = 'a'; chars[3] <= 'z' && !done; chars[3]++) {
                        for (chars[4] = 'a'; chars[4] <= 'z' && !done; chars[4]++) {
                            //the String creation is necessary to get the encoding right
                            String canidate = new String(chars);
                            //genenrate SHA-256 hash using Java's standard facilities
                            byte[] hash = digest.digest(canidate.getBytes());
                            if (Arrays.equals(hash, crackMe)) {
                                match = canidate;
                                done = true;
                            }
 
                        }
                    }
                }
            }
        }
        System.out.println(String.format("Hash %s has the following match : %s", crackMeString, match));
    }
}
 
 
 