Ehab Younes Ehab Younes - 1 year ago 70
C Question

Crack function for encrypted passwords with C’s DES-based, not working?

I'm making a program in C to crack DES-based encrypted password, It takes the password as an argument and gives me the password.

What I did was trying 500000 words by encrypting them in the same salt (first 2 letters) and then compare it with argv[1] (which is the encrypted password that I want to crack). I think it's called brute force (trying everything possible).
anyway my problem is when I encrypt the words I get different encryption (same salt and same key) as you see I print the number, words and the encryption (just to check if it works) you can remove them if you want!

btw I got the code that reads the line from file from some website, since I'm new to C and I haven't learnt about files yet!

Please be gentle I'm really new here :D, and if you got a comment of the design or code just tell me :)!

BTW I'm taking cs50 course from XHarved, and this is in the hacker edition, so I don't have to do it. It's like extra homework!

Example: when I crypt the word "crimson" in the crypt function it becomes 50yoN9fp966dU but when I import it from a file and then crypt it, it's something else (50fy...).

Sorry for the long question :|!

See it if you want:

#include <stdio.h>
#include <unistd.h>
#include <cs50.h>
#include <string.h>


char *crypt(const char *key, const char *salt);

int main(int argc, char *argv[])
static string cryptedText[500000];
static char word[500000][50];
string salt;
int i = 0;

if (argc != 2)
return 1;

FILE *fp;

printf("Unable to open file.\n");

// the first 2 characters are the salt.
salt = strcat(&argv[1][0], &argv[1][1]);

/*crypt every word in wordsTest with the same "salt" and
test if it equals argv[1](crypted pass) */

printf("%i ----> %s",i , word[i]);

cryptedText[i] = crypt(word[i], salt);
printf("%s\n", cryptedText[i]);


while (strcmp(cryptedText[i - 1], argv[1]) != 0);

printf ("%s\n", word[i - 1]);


I think the cryptedText variable doesn't need to be 500000 (I can overwritte it everytime)

Answer Source

As noted in my comment:

The input from fgets() includes the newline; you don't eliminate it. Therefore, you're comparing the encryption of "crimson" with "crimson\n" and the answers must be different.

You mentioned in a comment:

…for some reason I had to replace the strcmp (it didn't compare like it's supposed to) in the while loop to strncmp and set the "int n" to 13.

With general encryption, since the encrypted data is a blob of binary data that might include embedded null bytes '\0', you would probably use memcmp() rather than use either strcmp() or strncmp().

However, since you're using crypt(), the output has an encoding similar to Base-64. It produces a (fixed length) string, but you have to copy that string to preserve the value. It will be overwritten by the next call to crypt(). So, you are probably busy stashing the same pointer into the array of pointers. (Aside: that <cs50.h> header, and in particular its string type, are annoying!)


To be of any use, defines like #define _XOPEN_SOURCE must appear before any system headers are included. Also, you should specify the version number you want; you should probably use 600 or 700, depending on what your platform supports. You shouldn't have to write the declaration of the crypt() function in your code. The problem occurred because the #define _XOPEN_SOURCE was misplaced and misvalued.

Also, the line salt = strcat(&argv[1][0], &argv[1][1]); is weird and invokes undefined behaviour. It is weird because it tries to add the string starting at the second character of argv[1] to the end of argv[1], and invokes undefined behaviour because (a) the strings overlap and (b) you're writing into space that isn't available.