
+ Removes an useless nested for-loop + Removes an useless dynamic allocation + Limits the number of affectations and conditions by formatting data before running hashing operations
175 lines
4.8 KiB
C
175 lines
4.8 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <inttypes.h>
|
|
|
|
#include <regex.h>
|
|
#include <openssl/evp.h>
|
|
|
|
|
|
#define MAX_LENGTH 32
|
|
|
|
#define HEX_DIGEST_MAX_LENGTH ((EVP_MAX_MD_SIZE * 2) + 1)
|
|
|
|
|
|
void compute_digest_against_evp(
|
|
const EVP_MD *const evp_md_sha,
|
|
const char *const message_candidate, const size_t message_candidate_length,
|
|
unsigned char *const hash_digest, unsigned int *const hash_digest_length)
|
|
{
|
|
EVP_MD_CTX *md_ctx = EVP_MD_CTX_create();
|
|
EVP_DigestInit_ex(md_ctx, evp_md_sha, NULL);
|
|
EVP_DigestUpdate(md_ctx, message_candidate, message_candidate_length);
|
|
EVP_DigestFinal_ex(md_ctx, hash_digest, hash_digest_length);
|
|
EVP_MD_CTX_destroy(md_ctx);
|
|
}
|
|
|
|
|
|
void check_and_store_result(
|
|
const char *const hash_method_name,
|
|
regex_t *const preg,
|
|
const char *const message_candidate,
|
|
const char *const hash_digest_hexadecimal)
|
|
{
|
|
if(regexec(preg, hash_digest_hexadecimal, 0, NULL, 0) == 0)
|
|
{
|
|
FILE *f_magic_hashes = fopen("magic_hashes.txt", "a");
|
|
if(f_magic_hashes == NULL)
|
|
{
|
|
regfree(preg);
|
|
EVP_cleanup();
|
|
fprintf(stderr, "Could not open (or create ?) \"magic_hashes.txt\" file : %s\n", strerror(errno));
|
|
exit(-1);
|
|
}
|
|
|
|
fprintf(f_magic_hashes, "[openssl_%s]\t%s\t%s\n", hash_method_name, message_candidate, hash_digest_hexadecimal);
|
|
|
|
if(fclose(f_magic_hashes) != 0)
|
|
{
|
|
regfree(preg);
|
|
EVP_cleanup();
|
|
fprintf(stderr, "Could not close \"magic_hashes.txt\" file : %s\n", strerror(errno));
|
|
exit(-1);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void raw_digest_to_hexadecimal(
|
|
const unsigned char *const hash_digest, const unsigned int hash_digest_length,
|
|
char *const hash_digest_hexadecimal)
|
|
{
|
|
memset(hash_digest_hexadecimal, 0, HEX_DIGEST_MAX_LENGTH * sizeof(*hash_digest_hexadecimal));
|
|
for(unsigned int i = 0; i < hash_digest_length; i++)
|
|
{
|
|
sprintf(hash_digest_hexadecimal + (i * 2), "%02x", hash_digest[i]);
|
|
}
|
|
}
|
|
|
|
|
|
int main(int argc, char const *argv[])
|
|
{
|
|
(void)argc;
|
|
(void)argv;
|
|
|
|
// We will generate "plausible" password strings, up to 32-character long.
|
|
const char *const char_pool = {
|
|
"abcdefghijklmnopqrstuvwxyz"
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
"0123456789"
|
|
"!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"
|
|
};
|
|
const size_t char_pool_length = strlen(char_pool);
|
|
|
|
// Compile "Magic Hashes" format REGEXP.
|
|
regex_t preg;
|
|
int err = regcomp(&preg, "^0+e[:digit:]+$", REG_NOSUB | REG_EXTENDED);
|
|
if(err != 0)
|
|
{
|
|
regfree(&preg);
|
|
fprintf(stderr, "Could not compile REGEXP pattern : %s\n", strerror(err));
|
|
exit(-1);
|
|
}
|
|
// _____________________________________
|
|
|
|
// Cryptographic stuffs.
|
|
unsigned char hash_digest[EVP_MAX_MD_SIZE];
|
|
unsigned int hash_digest_length;
|
|
char hash_digest_hexadecimal[HEX_DIGEST_MAX_LENGTH];
|
|
|
|
OpenSSL_add_all_algorithms();
|
|
const EVP_MD *const evp_md_sha224 = EVP_sha224();
|
|
const EVP_MD *const evp_md_sha256 = EVP_sha256();
|
|
const EVP_MD *const evp_md_sha384 = EVP_sha384();
|
|
const EVP_MD *const evp_md_sha512 = EVP_sha512();
|
|
// _____________________
|
|
|
|
// Loop variables.
|
|
uint16_t i, j;
|
|
uint16_t indexes[MAX_LENGTH + 1] = {0};
|
|
char message_candidate[MAX_LENGTH + 1] = "";
|
|
// _______________
|
|
|
|
for(i = 0; ; )
|
|
{
|
|
// Update our message candidate according to previous indexes, for the current iteration.
|
|
for(j = i; ; j--)
|
|
{
|
|
if(indexes[j] >= char_pool_length)
|
|
{
|
|
indexes[j] = 0;
|
|
message_candidate[j] = char_pool[indexes[j]++];
|
|
|
|
if(j == 0)
|
|
{
|
|
i++;
|
|
message_candidate[i] = char_pool[indexes[i]++];
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
message_candidate[j] = char_pool[indexes[j]++];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(i >= MAX_LENGTH)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// SHA224
|
|
compute_digest_against_evp(evp_md_sha224, message_candidate, i + 1, hash_digest, &hash_digest_length);
|
|
raw_digest_to_hexadecimal(hash_digest, hash_digest_length, hash_digest_hexadecimal);
|
|
check_and_store_result("sha224", &preg, message_candidate, hash_digest_hexadecimal);
|
|
// ______
|
|
|
|
// SHA256
|
|
compute_digest_against_evp(evp_md_sha256, message_candidate, i + 1, hash_digest, &hash_digest_length);
|
|
raw_digest_to_hexadecimal(hash_digest, hash_digest_length, hash_digest_hexadecimal);
|
|
check_and_store_result("sha256", &preg, message_candidate, hash_digest_hexadecimal);
|
|
// ______
|
|
|
|
// SHA384
|
|
compute_digest_against_evp(evp_md_sha384, message_candidate, i + 1, hash_digest, &hash_digest_length);
|
|
raw_digest_to_hexadecimal(hash_digest, hash_digest_length, hash_digest_hexadecimal);
|
|
check_and_store_result("sha384", &preg, message_candidate, hash_digest_hexadecimal);
|
|
// ______
|
|
|
|
// SHA512
|
|
compute_digest_against_evp(evp_md_sha512, message_candidate, i + 1, hash_digest, &hash_digest_length);
|
|
raw_digest_to_hexadecimal(hash_digest, hash_digest_length, hash_digest_hexadecimal);
|
|
check_and_store_result("sha512", &preg, message_candidate, hash_digest_hexadecimal);
|
|
// ______
|
|
}
|
|
|
|
// Free allocations.
|
|
regfree(&preg);
|
|
EVP_cleanup();
|
|
// _________________
|
|
|
|
return 0;
|
|
}
|