6

What I am searching for is a decrypt function to the crypt(3) function. Reading the manual they only refer me to see login(1), passwd(1), encrypt(3), getpass(3), passwd(5), but as far as I am aware, non of them can be used to decrypt the string.

I wrote together a small program to show my point, the function I am looking for is the somefunctogetbackplaintext(...)

#define _XOPEN_SOURCE
#include <unistd.h>
#include <string.h>
#include <stdio.h>

int
main(int argc, char *argv[])
{
  char *cryptated = crypt(argv[1], "aa"); // Password and salt
  if(strcmp("somepassword", somefunctogetbackplaintext(argv[1], cryptated, "aa"))) //Plain text, cryptated string, salt
    {
      printf("Success!\n");
    }
  else
    {
      printf("Not a success!\n");
    }

  return 0;
}
melpomene
  • 84,125
  • 8
  • 85
  • 148
Salviati
  • 758
  • 2
  • 9
  • 28
  • 5
    What makes you think that a password actually can be decrypted? The usual password mechanisms do not need that. Actually I believe that the idea is that they can NOT be decrypted. – Yunnosch Feb 02 '19 at 19:59
  • 1
    I'm pretty sure crypt is a one-way hash, like MD5. – grooveplex Feb 02 '19 at 20:00
  • 1
    You have read the docs correctly - _non[e] of them can be used to decrypt the string_ – ryyker Feb 02 '19 at 20:02
  • So it is not possible? Personally never worked with one-way encryption, only two way. Completely flew over my head, then all I have to do is to encrypt the string with the same salt and compare the encrypted one? Edit: Yes, it is. Thank you! – Salviati Feb 02 '19 at 20:03
  • 1
    @Salviati - yes, that is how passwords etc. typically are implemented. Hashed, therefore not decryptable. – ryyker Feb 02 '19 at 20:04
  • @ryyker, but the [documentation](https://linux.die.net/man/3/crypt) says "It is based on the Data Encryption Standard algorithm", and DES _is_ decryptable, just like any other _encryption_ algorithm, isn't it? – ForceBru Feb 02 '19 at 20:06
  • 1
    @ForceBru Traditional `crypt` uses the password as a 56-bit DES key and uses it to encrypt a block of all zeroes. It does not encrypt the password itself. – melpomene Feb 02 '19 at 20:12
  • The root cause of the misunderstanding here is the man page that states `crypt, crypt_r - password and data encryption` as well as the name of the function itself. This let me to believe as well that it encrypts the password and not hashes it and also made me wonder what key does the system use for this. – r3mus n0x Feb 02 '19 at 20:26

3 Answers3

3

crypt does not encrypt passwords (so there is no way to decrypt them). Instead it hashes a given password, producing a string that is impossible to reverse to the original password (because the hash function loses information in the process). The most practical way to attack crypt and recover passwords from their hashes is probably some sort of dictionary attack.

However, none of that is necessary to check whether a given password is correct:

const char *password_and_salt = ...;  // e.g. from getpwent or a database
const char *input = argv[1];
if (strcmp(crypt(input, password_and_salt), password_and_salt) == 0) {
    printf("your password is correct\n");
}

In other words, you pass the user input to crypt and check whether it matches the known result of an earlier crypt. If so, the passwords match.

melpomene
  • 84,125
  • 8
  • 85
  • 148
2

Here is a summary excerpt from this article distinguishing between the concepts of encryption and Hashing:

Passwords remain the primary means for online authentication and must be protected when stored on a server. Encryption is an option, but it has an inherent weakness in this application because the server authenticating the password must have the key to decrypt it. An attacker who steals a file of encrypted passwords might also steal the key.

Hashing is a better option, especially with the judicious use of salt, according to mathematician Andrew Regenscheid and computer scientist John Kelsey of the National Institute of Standards and Technology’s Computer Security Division.

Encryption is a two-way function; what is encrypted can be decrypted with the proper key. Hashing, however, is a one-way function that scrambles plain text to produce a unique message digest. With a properly designed algorithm, there is no way to reverse the hashing process to reveal the original password. An attacker who steals a file of hashed passwords must then guess the password.
(emphasis mine)

Also (from comments) this link plainly states: crypt is the library function which is used to compute a password hash...

ryyker
  • 22,849
  • 3
  • 43
  • 87
2

As wikipedia article about crypt states:

Excerpt 1:

crypt is the library function which is used to compute a password hash that can be used to store user account passwords while keeping them relatively secure (a passwd file).

Excerpt 2:

This is technically not encryption since the data (all bits zero) is not being kept secret; it's widely known to all in advance. However, one of the properties of DES is that it's very resistant to key recovery even in the face of known plaintext situations. It is theoretically possible that two different passwords could result in exactly the same hash. Thus the password is never "decrypted": it is merely used to compute a result, and the matching results are presumed to be proof that the passwords were "the same."

So that is the answer to question: "the password is never "decrypted""

Alex Yu
  • 3,412
  • 1
  • 25
  • 38