Given that the rule of thumb is to store salted hashes of the password string, not the encrypted form of it, why does the PHP crypt() function use the DES-based algorithms? Isn't DES an encryption algorithm? The manual says
... crypt() will return a hashed string using the standard Unix DES-based algorithm or alternative algorithms that may be available on the system ...
What I understand from here is that crypt() only uses the algorithm as implemented by the system. And surely DES is implemented as an encryption algorithm rather than a custom hashing algorithm for crypt.
PS - I know that DES was way back in the past and nobody should use it anymore.
The idea of DES-based password hashing is, basically, to encrypt a block of zeroes with the password and passed salt for some number of rounds. Any half-decent encryption makes key recovery hard even in the face of known plaintext, so that’s why it’s possible to make strong password hashes out of encryption functions.
I think the PHP default is compatible with this scheme.
Related
I am working on a registration form where I need to encrypt password, I've heard that it is recommended for me to use the Blowfish encryption for passwords, How do you implement a blowfish encryption using PHP crypt() function? also, I am planning to retrieve the password later for logging in.
The short answer is use crypt with a salt beginning with the characters $2a$, a two digit cost parameter, $, and 22 digits from the alphabet ./0-9A-Za-z. That only works on systems that support the Blowfish encryption algorithm. However, PHP 5.3 implements it natively. See PHP manual — crypt for more details.
Example:
crypt('rasmuslerdorf', '$2a$07$somesillystringforsalt')
The salt string triggers the appropriate algorithm. The two digit cost parameter is the base-2 logarithm of the iteration count for the underlying Blowfish-based hashing algorithm and must be in range [04 – 31]. In the example 07 tells the algorithm to use 27 or 128 iterations. The higher this number, the longer it will take to execute BUT, in the context of hashing user passwords, that is a GOOD thing.
This answer to a similar question explains in more detail what BCrypt is,how it relates to Blowfish, and why you should use it. There are many other related topics here on Stack Overflow.
phpass is an excellent, easy to use password hashing framework that works on all systems, using Blowfish if it’s supported, and falling back to other algorithms if it’s not.
You should never need blowfish to encrypt a password like this. The registration form should be over HTTPS, which will handle defense against an attacker on the wire. The password its self should be hashed (never encrypted). bcrypt is a good password hash function based on blowfish. But there are plenty of posts related to secure password storage on SO.
So far I have been using md5 to hash passwords on my site, no salt.
Now I am building an application that will have to be more secure and I'm reading md5 can be easily brute-force attacked.
So I want to use crypt() to hash the passwords.
What I have not fully understood is:
Do I have to provide a salt or is the built-in generated one ok?
How many times (if more than one) should I iterate the crypt function to be safe?
With md5, no matter the length of the input string, the hash was 32-digit. Does crypt return a standard length of hashes too?
You need to provide a salt, if you want to specify encryption other than DES. Otherwise, you're good with the default salt.
You don't iterate the crypt function yourself, this is done internally with algorithms where it makes sense. Number of iterations is specified via the salt.
Yes, the hash length of a given hash algorithm is standard; different hash algorithms have different hash lengths, however.
crypt can use different hash algorytms. With md5 it returns 128 bit integer (with 32 chars hex representation). Using crypt with a salt once is safe enought. It's recommended the salt to be provided by the application
An optional salt string to base the hashing on. If not provided, the
behaviour is defined by the algorithm implementation and can lead to
unexpected results.
My question is how do I get the same result from mcrypt as I would get from crypt, with respect to blowfish?
I am wanting to use the phpass framework for password hashing and verifying. Which works really well as long has you have PHP 5.3 because blowfish is included with crypt().
My host is running PHP 5.2.x with the mcrypt library.
Going through the docs and googling about blowfish with crypt, it appears that the result is '$a2$', the two character iteration value, '$', the salt ( padded or cut to 22 characters ), then a 32 base64 string representing the hash.
My problem is I can't find explanations of the MCRYPT_MODE_modenames that make sense to me. And how do I feed mcrypt() the number of iterations I want? Or are the two functions using different forms of blowfish that dont cross translate?
Mcrypt, and crypt() are two totally different functions. Mcrypt is two-way encryption, whereas crypt is one-way encryption. As far as I am aware crypt() is inside of php 5.2. Also, if I was you I'd just reference crypt() itself. And I'd also use bcrypt from it.
$hashed_password=crypt($password_to_be_hashed,'$2a$04$saltstringhere');
Finally, just change the two digit cost factor inside of the two digits after the $2a$. That will allow you to change the amount of cputime that is going to be required for it. Remember it goes up logarithmically(if i remember correctly). The default value is 07.
Finally crypt_blowfish is the two-way encryption algorithm of blowfish that takes keys up to 448 bits. The blowfish inside of crypt is bcrypt, is based upon blowfish but was designed for storing passwords as it hashes them. This is known as one-way encryption.
Are DES Encryption called "One Way Encryption" or "two way Encryption" ?
Are there a PHP class or method to decrypt the DES Encryption ?
The php crypt function is a one-way hashing function, if you want to be able to decrypt, take a look at the mcrypt extension which supports a range of algorithms
It should be noted that there are (and have always been) questions surrounding the DES algorithm. It's been widely in use for a long time, but since it was originally specified with only a 56 bit key, it's questionable whether it's secure enough for any important uses at this point. Triple DES is generally better, but there are some known theoretical attacks. If you have a choice of cipher, you might want to look at AES instead.
DES can be reversed, so it's a two-way encryption (if you meant that).
DES is a pretty well known encryption standard so it should be available in PHP too.
One-way encryption is a secure form of hashing: the plaintext is changed into an apparently random sequence of data, often of fixed length, in such a way that the original plaintext (theoretically) cannot be retrieved without a brute-force effort.
Two-way encryption, or reversible encryption is what we normally mean by the term encryption: the plaintext is transformed into apparently random data, but in a way that relies on a "key" that allows the original plaintext to be retrieved.
DES is a form of reversible encryption that is relatively weak by today's standards, as it relies on a 56-bit key (14 hex characters). It has been superseded by 3DES, or triple-DES, which is essentially the same algorithm with a longer key.
You don't mention your application, but if you need only to compare the data and not retrieve it, hashing is considered more secure. For example, you can store hashed passwords; then, when a user authenticates, perform the same hash on the entered text and compare it with the stored hashed value. If they match, the correct password was entered.
A significant advantage to hashing is that you don't need to store a decryption key.
I am not familiar with the "one way encryption" or "two way encryption" terms. There is a term "one time password" (totally irrelevant for DES), and there are "symmetric" and "assymetric" encryption algorithms, meaning whether the same key is used for encryption and decryption (symmetric) or a set of two different keys is used one for encryption and another for decryption (assymetric). DES is a symmetric algorithm. As for PHP, crypt() since to be doing the job:
http://us2.php.net/crypt
I Think you probably mean a one-way function [1]. In cryptography one distinguishes between symmetric and asymmetric cryptography. Symmetric cryptography uses the same key to encrypt and decrypt (DES is symmetric). Asymmetric Cryptography is used for key exchange and a public key is used to encrypt the message, while the private key is used to decrypt it. An example of Asymmetric Cryptography is AES [2]. Asymmetric cryptography uses one way functions.
[1] http://en.wikipedia.org/wiki/One-way_function
[2] http://en.wikipedia.org/wiki/AES
I'm trying to create system users with a php script securely, In that, I'd like to be able to hash the password with the php script, so that their password shows up nowhere in the bash history.
How to I take a string, and hash it so it is a unix password hash?
$UX_PW = some_function('my_password');
exec("useradd -p $UX_PW newusername");
It's crypt() that implements the UNIX password hashing.
http://us.php.net/manual/en/function.crypt.php
Depending on your system, you're either looking for crypt() or md5().
Traditionally, unix uses DES-encrypted passwords (thats the 'crypt' function), with a 2-character salt (two random characters from the set [a-zA-Z0-9./]) which is prepended to the hash to perturb the algorithm.
Newer systems often use MD5 though.
Use crypt. Recent linux/unixes use CRYPT_MD5 or
CRYPT_BLOWFISH. MD5 is the most widely supported one. DES's are for old systems.
Also I should note that the MD5 version is not a simple MD5 sum operation, it also uses a "salt" value to make hashes not-precalculatable. [[ I made up this term :) ]]
The password-hashing used on UNIX, Linux, and other UNIX-like POSIX operating systems varies a lot. Most "passwd" hashing methods uses a modified DES algorithm (not true DES), they may apply the hashing to the input multiple times, and they use a salt of 16 or 24 bits. A specific answer of the method to produce a passwd-compatible hash depends on which operating system you're using.
The crypt() system call should be the way to do password hashing according to your operating system. You can access it in PHP using the function crypt().
As for which crypt algorithm to use, this depends on your operating system.
From the Ubuntu Intrepid man page on passwd (change password)
The security of a password depends upon the strength of the encryption algorithm and the size of the key space. The UNIX System encryption method is based on the
NBS DES algorithm and is very secure. The size of the key space depends upon the randomness of the password which is selected.
Also, instead of using crypt() you may prefer hash() because this allows you to keep the string setting for the hash algorithm elsewhere. If your code needs to use a different hash algorithm for other environments, you'll only have to change the string and not the name of the function.