Skip to content

Instantly share code, notes, and snippets.

@ql-owo-lp
Last active October 12, 2018 12:17
Show Gist options
  • Save ql-owo-lp/5280376 to your computer and use it in GitHub Desktop.
Save ql-owo-lp/5280376 to your computer and use it in GitHub Desktop.
CIS 644 Lab 6 Hash function crack
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
void getHash(char * hashname, char *msg, unsigned char *md_value) {
EVP_MD_CTX *mdctx;
const EVP_MD *md;
//unsigned char md_value[EVP_MAX_MD_SIZE];
int md_len, i;
OpenSSL_add_all_digests();
md = EVP_get_digestbyname(hashname);
if(!md) {
printf("Unknown message digest %s\n", hashname);
exit(1);
}
mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, msg, strlen(msg));
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_destroy(mdctx);
// shrink the digest's length to 24 (3 words)
//strncpy( digt, md_value, 3);
}
void setRndStr(char *msg) {
int i;
for (i=0;i<11;i++)
msg[i] = rand()%256-128;
}
int crackOneWayHash(char * hashname) {
char msg1[11], msg2[11];
unsigned char digt1[EVP_MAX_MD_SIZE], digt2[EVP_MAX_MD_SIZE];
// we do not need to generate words, instead generating number only
int count=0, i;
setRndStr(msg1);
//sprintf(msg1, "%d", rand()); // convert to string
// get an initial message
getHash(hashname, msg1, digt1);
// run the crack
do {
//sprintf(msg2, "%d", rand()); // convert to string
setRndStr(msg2);
getHash(hashname, msg2, digt2);
count++;
} while (strncmp(digt1, digt2, 3)!=0);
//printf("\n cracked after %d tries! %s and %s has same digest ", count, msg1, msg2);
printf("cracked after %d tries! same digest ", count, msg1, msg2);
for(i = 0; i < 3; i++) printf("%02x", digt1[i]);
printf("\n");
return count;
}
int crackCollisionHash(char * hashname) {
char msg1[11], msg2[11];
unsigned char digt1[EVP_MAX_MD_SIZE], digt2[EVP_MAX_MD_SIZE];
// we do not need to generate words, instead generating number only
int count=0, i;
// run the crack
do {
//sprintf(msg1, "%d", rand()); // convert to string
setRndStr(msg1);
getHash(hashname, msg1, digt1);
//sprintf(msg2, "%d", rand()); // convert to string
setRndStr(msg2);
getHash(hashname, msg2, digt2);
count++;
} while (strncmp(digt1, digt2, 3)!=0);
//printf("\n cracked after %d tries! %s and %s has same digest ", count, msg1, msg2);
printf("cracked after %d tries! same digest ", count);
for(i = 0; i < 3; i++) printf("%02x", digt1[i]);
printf("\n");
return count;
}
main(int argc, char *argv[])
{
char *hashname;
if(!argv[1])
// set to md5 by default
hashname = "md5";
else
hashname = argv[1];
srand((int)time(0)); // init random seed
int i,count;
for (i=0,count=0;i<15;i++)
count+=crackCollisionHash(hashname);
printf("average time cracking collision-free: %d \n", count/15);
for (i=0,count=0;i<5;i++)
count+=crackOneWayHash(hashname);
printf("average time cracking one-way: %d \n", count/5);
}
INC=/usr/local/ssl/include/
LIB=/usr/local/ssl/lib/
all:
gcc -I$(INC) -L$(LIB) -o digt digt.c -lcrypto
#!/bin/bash
# This is bash!! do not run it using "sh"!
# set the file which we want to hash
FILE1="Testfile1"
FILE2="Testfile2"
# you also can try sha256 / md5
ENCRY="md5"
echo 'Running.. Please wait'
# upper case H1 and H2, for ibase/obase convertion
declare -u H1
declare -u H2
H1=`openssl dgst -$ENCRY $FILE1 | awk '{print $2}'`
H2=`openssl dgst -$ENCRY $FILE2 | awk '{print $2}'`
echo "The hash value (in HEX) of $FILE1 is $H1."
echo "The hash value (in HEX) of $FILE2 is $H2."
BITS1=`echo "ibase=16;obase=2;$H1" | bc`
BITS2=`echo "ibase=16;obase=2;$H2" | bc`
# now count how many bits are actually different (the "one" bits)
BITS1=`echo "$BITS1" | sed 's/\\\r*//g'`
BITS2=`echo "$BITS2" | sed 's/\\\r*//g'`
LEN=`expr length "$BITS1"`
COUNT=0
for i in `seq 1 $LEN`
do
B1=$(echo $BITS1 | awk "{print substr (\$0, $i, 1)}")
B2=$(echo $BITS2 | awk "{print substr (\$0, $i, 1)}")
if [ "$B1" -ne "$B2" ]; then
COUNT=`expr $COUNT + 1`
fi
done
echo "$COUNT bits are different."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment