Last active
October 12, 2018 12:17
-
-
Save ql-owo-lp/5280376 to your computer and use it in GitHub Desktop.
CIS 644 Lab 6 Hash function crack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
INC=/usr/local/ssl/include/ | |
LIB=/usr/local/ssl/lib/ | |
all: | |
gcc -I$(INC) -L$(LIB) -o digt digt.c -lcrypto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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