You cannot decrypt a string that has been encrypted in this way. It's normally used one way, first to encrypt a string, and then to encrypt a password to compare against the encrypted string. If you're using it in this form, then consider supplying the encrypted password as the SALT.
So the exact return value of crypt is system dependent, but it often uses an algorithm that only looks at the first 8 byte of the password. These two things combined make it a poor choice for portable password encryption. If you're using a system with a stronger encryption routine and don't try to check those passwords on incompatible systems, you're fine. But it sounds like you're using an OS with the old crappy DES routine.
I am trying to generate a unique string/id given another relatively large string(consisting of a directory path name), thought of using crypt function. However, it's not working as expected, most probably due to my inability to understand.
I just started learning Perl and I have a task to compare user input variable with SHA-512 stored hashed password. I made below function to test. I use randomly generated salt to generate digest from real password (p2). Next, I use this digest as salt for my user entered password (p1) to be compared with digest value. This is based on description I have found here.I use crypt function to generate digest, however I am not able to display or compare it in next if step.The password should be hashed using SHA-512.I appreciate your help.
crypt is a thin wrapper around the C crypt function. Its implementation will vary from environment to environment. Here on OS X it does not take a leading $x$ to indicate which algorithm to use, it just uses DES. crypt("foo", '$6$'.$salt); results in $6A86JNndVTdM. Only the first two bytes of the salt are used, $6.
crypt and DES are inappropriate for password hashing. Its short key makes it very easy to defeat, and its salt is just two characters. SHA-512 is also not appropriate for password hashing, it's too fast. Instead, you want a dedicated password hashing function such as bcrypt or PBKDF2 and other key stretching algorithms. Some implementations of crypt can do bcrypt, many can not.
crypt is a one-way hash function. The PLAINTEXT and SALT are turned into a short string, called a digest, which is returned. The same PLAINTEXT and SALT will always return the same string, but there is no (known) way to get the original PLAINTEXT from the hash. Small changes in the PLAINTEXT or SALT will result in large changes in the digest.
There is no decrypt function. This function isn't all that useful for cryptography (for that, look for Crypt modules on your nearby CPAN mirror) and the name "crypt" is a bit of a misnomer. Instead it is primarily used to check if two pieces of text are the same without having to transmit or store the text itself. An example is checking if a correct password is given. The digest of the password is stored, not the password itself. The user types in a password that is crypt'd with the same salt as the stored digest. If the two digests match, the password is correct.
When verifying an existing digest string you should use the digest as the salt (like crypt($plain, $digest) eq $digest). The SALT used to create the digest is visible as part of the digest. This ensures crypt will hash the new string with the same salt as the digest. This allows your code to work with the standard crypt and with more exotic implementations. In other words, assume nothing about the returned string itself nor about how many bytes of SALT may matter.
When choosing a new salt create a random two character string whose characters come from the set [./0-9A-Za-z] (like join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]). This set of characters is just a recommendation; the characters allowed in the salt depend solely on your system's crypt library, and Perl can't restrict what salts crypt accepts.
If using crypt on a Unicode string (which potentially has characters with codepoints above 255), Perl tries to make sense of the situation by trying to downgrade (a copy of) the string back to an eight-bit byte string before calling crypt (on that copy). If that works, good. If not, crypt dies with Wide character in crypt.
Absolutely doesn't cut it unless the key is never reused. Usually that means that the IV is created using a cryptographically secure random number generator. There are of course other ways to get an unpredictable IV, such as encryption of a counter with another key, but those are very uncommon.
Well yes. Let's take a look at CBC mode encryption (decryption is similar of course, except that the XOR with the IV or previous ciphertext is performed after the block cipher has been applied):
If you do not store or cannot derive the key for the ciphertext then you're doing something wrong, yes. If you're storing keys you would generally use a mode like AES-SIV or key wrapping (or you'd use a key derivation function, a ratchet, etc.).
The IV randomizes the ciphertext, and must be unique for each message. For CBC mode, it MUST be unpredictable. It need not be secret, it's usually prepended to the ciphertext. It MUST NOT repeat for a given key, and you MUST use a Message Authentication Code (MAC) over the ciphertext and IV for CBC to be secure against common attacks. The recipient MUST validate the MAC before attempting decryption, and MUST NOT continue to decrypt if the validation fails.
crypt is the password encryption function. It is based on the Data Encryption Standard algorithm with variations intended (among other things) to discourage use of hardware implementations of a key search.
By taking the lowest 7 bit of each character of $plaintext (filling it up to 8 characters with zeros, if needed), a 56-bit key is obtained. This 56-bit key is used to encrypt repeatedly a constant string (usually a string consisting of all zeros). The returned value points to the encrypted password, a series of 13 printable ASCII characters (the first two characters represent the salt itself).
The DES algorithm itself has a few quirks which make the use of the crypt(3) interface a very poor choice for anything other than password authentication. If you are planning on using the crypt(3) interface for a cryptography project, don't do it: get a good book on encryption and one of the widely available DES libraries.
crypt is a POSIX C library function. It is typically used to compute the hash of user account passwords. The function outputs a text string which also encodes the salt (usually the first two characters are the salt itself and the rest is the hashed result), and identifies the hash algorithm used (defaulting to the "traditional" one explained below). This output string forms a password record, which is usually stored in a text file.
There is an unrelated crypt utility in Unix, which is often confused with the C library function. To distinguish between the two, writers often refer to the utility program as crypt(1), because it is documented in section 1 of the Unix manual pages, and refer to the C library function as crypt(3), because its documentation is in manual section 3.[1]
Modern Unix implementations of the crypt library routine support a variety of hash schemes. The particular hash algorithm used can be identified by a unique code prefix in the resulting hashtext, following a de facto standard called Modular Crypt Format.[2][3][4]
Over time various algorithms have been introduced. To enable backward compatibility, each scheme started using some convention of serializing the password hashes that was later called the Modular Crypt Format (MCF).[3] Old crypt(3) hashes generated before the de facto MCF standard may vary from scheme to scheme. A well-defined subset of the Modular Crypt Format was created during the Password Hashing Competition.[3] The format is defined as:[10]
The original implementation of the crypt() library function[11] in Third Edition Unix[12] mimicked the M-209 cipher machine. Rather than encrypting the password with a key, which would have allowed the password to be recovered from the encrypted value and the key, it used the password itself as a key, and the password database contained the result of encrypting the password with this key.
The original password encryption scheme was found to be too fast and thus subject to brute force enumeration of the most likely passwords.[11] In Seventh Edition Unix,[13] the scheme was changed to a modified form of the DES algorithm. A goal of this change was to make encryption slower. In addition, the algorithm incorporated a 12-bit salt in order to ensure that an attacker would be forced to crack each password independently as opposed to being able to target the entire password database simultaneously.
In detail, the user's password is truncated to eight characters, and those are coerced down to only 7-bits each; this forms the 56-bit DES key. That key is then used to encrypt an all-bits-zero block, and then the ciphertext is encrypted again with the same key, and so on for a total of 25 DES encryptions. A 12-bit salt is used to perturb the encryption algorithm, so standard DES implementations can't be used to implement crypt(). The salt and the final ciphertext are encoded into a printable string in a form of base64.
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."
The traditional DES-based crypt algorithm was originally chosen because DES was resistant to key recovery even in the face of "known plaintext" attacks, and because it was computationally expensive. On the earliest Unix machines it took over a full second to compute a password hash. This also made it reasonably resistant to dictionary attacks in that era. At that time password hashes were commonly stored in an account file (/etc/passwd) which was readable to anyone on the system. (This account file was also used to map user ID numbers into names, and user names into full names, etc.).
aa06259810