Using crypt() from crypt.h

10,395

(I am not familiar with CS50. I am answering this question under the assumption that crypt is the function crypt(3) from the traditional Unix standard C library.)

crypt is a very old function, from the days before anyone worried about thread-safety in C. Every time you call it, it returns the same pointer, pointing to a static buffer inside the C library. Each call overwrites the result of any previous call.

If you print out the result of the first crypt call before calling it again...

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

int 
main(void)
{
    char password[] = "AAAA";
    char toCrack[] = "AAzz";
    printf("%s\n", password);
    printf("%s\n", toCrack);

    char *toCrackCiph = crypt(toCrack, "da");
    printf("%s\n", toCrackCiph);

    char *passwordCiph = crypt(password, "aa");
    printf("%s\n", passwordCiph);
    return 0;
}

... then you will see two different strings. The output on my computer is

AAAA
AAzz
daeBW5vt16USo
aaI8pRQwCn7N2

Since you are using salt strings that request the old DES-based password hash algorithm, you should get the same thing.

This is a classroom exercise, but I must still point out that the old DES-based password hash can be broken by brute force on any modern computer, so it should never be used for real passwords. You can probably get a better algorithm to be used by specifying a different style of salt string, something like "$5$bpKU3bUSQLwX87z/$".

Share:
10,395
Zach LeFevre
Author by

Zach LeFevre

Updated on August 10, 2022

Comments

  • Zach LeFevre
    Zach LeFevre almost 2 years

    I am doing the week2 pset for CS50. When using the crypt function, the char pointers which point to the ciphertext of any string always point to the last thing I encrypted. For example:

    char password[] = "AAAA";
    char toCrack[] = "AAzz";
    printf("%s\n", password);
    printf("%s\n", toCrack);
    
    char *toCrackCiph = crypt(toCrack, "da");
    char *passwordCiph = crypt(password, "aa");
    
    
    printf("%s\n", passwordCiph);
    printf("%s\n", toCrackCiph);
    

    toCrackCiph and passwordCiph equal each other, even though their strings are not the same, and neither is the salt.

    Am I making a simple pointer error somewhere?

    Thanks,

  • abhisekp
    abhisekp over 4 years
    "old DES-based password hash can be broken by brute force" --- that's exactly what the Problem Set is about. Cracking the Hash by brute force 😁
  • abhisekp
    abhisekp over 4 years
    So how do I compare two outputs from crypt function call?
  • zwol
    zwol over 4 years
    @abhisekp You have to copy the string that crypt returns into another buffer before calling crypt again.
  • abhisekp
    abhisekp over 4 years
    I did this to copy the hash to another string (and not to the static hash location) char new_hash[14]; strcpy(new_hash, crypt(new_password, salt));