Thinking about to write a PHP script storing passwords in a DB, what php-crypto-function should i use?
Hashing is not an option, cause the passwords have to be stored cryted and able to be encrypted, so the user can see them.
Given your product's code function is to allow the user to view passwords, symmetric encryption is what you want.
Check out the API docs for mcrypt (MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)
Related
I use codeigniter a lot, however I am not really understanding why when I use the encryption library in version 3 the encryption string never comes out the same, even using the same salt/key.
So I have stored a user password as an encrypted string, which uses their own key to encrypt. The key is stored in the database. But when they come to login, and i want to encrypt the entered password to check the strings match, they never do match!
It seems the library always spits out different encrypted strings, no matter if the key is the same or not, how is this going to be useful if I can't match the stored encrypted password to the password they enter at login?
For example, password is 12456 with key a0956f251b9d957071005a2d11e4630a
SAVED PASSWORD IS: 0e6effa48949d6bf19e84530bc86e9a1407086b3b88fc368b6f8b7b53304b313eeebdb695c9cca10b3e7072f608bf4137e7fcc7d24fed54df2b6dcba3f94dcb6Tm05Qmay9G8JuUXps6UstWebmBmJ71BcIPgrW78OvSY=
PASSWORD GENERATED FROM USER LOGIN
6b893dac92155bc663b126b805c7189214ac4667b226f0c6fc22cf0c6bcca5e897c49961e8852ade1c3e85cbecab89df76ea7891727af6bf0bcc232b75d0d441LLUMZgOy4zLwAypuVQuK0lKTXrlXYptKpVdByytH2D8=
935c8f564c4a5ecb53510faa835eca8622069c34d534df6b9c2ea52de2d9bea5976128f6ff83a572ac677be4ebd690bc18e488518c2eed8b1b40a16c9e61d6b2hbKJ6B1VDuLPCXBeDDFzvrlSBIYCtN19M6dQGZRCvUE=
b8e020c7c10d564cfc3a9cc4d50b85ea3422422b73a2dd79930ead1fb601493279ba97645584d6dfa188e62f5eba5dc66d0dafdb7a82c08bf847bc84fc0718daSOVRrDlFmVMB/12ok9kR68ekXJcJvw0yfo/cnU9ojtI=
see they are different every time I try to encrypt the user input? It's not making any sense.
Likewise, if I try to decode the password in the database, with the same key it was encrypted with, I get nothing back, no decrypted password.
So, does anyone know what is going on here?
Randomized encryption is a security property necessary to achieve semantic security. If the encryption would not be randomized then an attacker might detect whether (prefixes of) messages were previously sent only by observing the ciphertexts. You generally don't want the attacker to know anything about the plaintexts except the length.
An encryption function has always a corresponding decryption function. It seems that you're only using one way of the two functions. You should never encrypt your user's passwords. You need to use hashing instead with some strong ones being PBKDF2, bcrypt, scrypt and Argon2. Since hash functions are one-way function, you won't be able to "decrypt" the hashes. In order to authenticate your user, you can run the password through the hash function again in order to compare with the hash that is stored in the database. See more: How to securely hash passwords?
Codigniter documentation:
DO NOT use this or any other encryption library for user password
storage! Passwords must be hashed instead, and you should do that via
PHP’s own Password Hashing extension.
http://www.codeigniter.com/userguide3/libraries/encryption.html
Fully explained here:
http://php.net/manual/en/faq.passwords.php
Try the md5 encryption its good and best till now.
In controller before send password like this:
md5($this->input->post('password));
or use hash() or SHA256/SHA512 they do it well.
It will do the trick.
Enjoy!
I use codeigniter a lot, however I am not really understanding why when I use the encryption library in version 3 the encryption string never comes out the same, even using the same salt/key.
So I have stored a user password as an encrypted string, which uses their own key to encrypt. The key is stored in the database. But when they come to login, and i want to encrypt the entered password to check the strings match, they never do match!
It seems the library always spits out different encrypted strings, no matter if the key is the same or not, how is this going to be useful if I can't match the stored encrypted password to the password they enter at login?
For example, password is 12456 with key a0956f251b9d957071005a2d11e4630a
SAVED PASSWORD IS: 0e6effa48949d6bf19e84530bc86e9a1407086b3b88fc368b6f8b7b53304b313eeebdb695c9cca10b3e7072f608bf4137e7fcc7d24fed54df2b6dcba3f94dcb6Tm05Qmay9G8JuUXps6UstWebmBmJ71BcIPgrW78OvSY=
PASSWORD GENERATED FROM USER LOGIN
6b893dac92155bc663b126b805c7189214ac4667b226f0c6fc22cf0c6bcca5e897c49961e8852ade1c3e85cbecab89df76ea7891727af6bf0bcc232b75d0d441LLUMZgOy4zLwAypuVQuK0lKTXrlXYptKpVdByytH2D8=
935c8f564c4a5ecb53510faa835eca8622069c34d534df6b9c2ea52de2d9bea5976128f6ff83a572ac677be4ebd690bc18e488518c2eed8b1b40a16c9e61d6b2hbKJ6B1VDuLPCXBeDDFzvrlSBIYCtN19M6dQGZRCvUE=
b8e020c7c10d564cfc3a9cc4d50b85ea3422422b73a2dd79930ead1fb601493279ba97645584d6dfa188e62f5eba5dc66d0dafdb7a82c08bf847bc84fc0718daSOVRrDlFmVMB/12ok9kR68ekXJcJvw0yfo/cnU9ojtI=
see they are different every time I try to encrypt the user input? It's not making any sense.
Likewise, if I try to decode the password in the database, with the same key it was encrypted with, I get nothing back, no decrypted password.
So, does anyone know what is going on here?
Randomized encryption is a security property necessary to achieve semantic security. If the encryption would not be randomized then an attacker might detect whether (prefixes of) messages were previously sent only by observing the ciphertexts. You generally don't want the attacker to know anything about the plaintexts except the length.
An encryption function has always a corresponding decryption function. It seems that you're only using one way of the two functions. You should never encrypt your user's passwords. You need to use hashing instead with some strong ones being PBKDF2, bcrypt, scrypt and Argon2. Since hash functions are one-way function, you won't be able to "decrypt" the hashes. In order to authenticate your user, you can run the password through the hash function again in order to compare with the hash that is stored in the database. See more: How to securely hash passwords?
Codigniter documentation:
DO NOT use this or any other encryption library for user password
storage! Passwords must be hashed instead, and you should do that via
PHP’s own Password Hashing extension.
http://www.codeigniter.com/userguide3/libraries/encryption.html
Fully explained here:
http://php.net/manual/en/faq.passwords.php
Try the md5 encryption its good and best till now.
In controller before send password like this:
md5($this->input->post('password));
or use hash() or SHA256/SHA512 they do it well.
It will do the trick.
Enjoy!
I am using php for a basic application to login into the system, be able to edit account information, and delete account. I have a mysql database. I need to encrypt/decrypt password using salt. How do I do it? Just need to make sure data is secure.
You don't want to encrypt passwords. You want to hash them.
Some reading:
http://php.net/manual/en/faq.passwords.php
Related SO post: how to hash the password and get it back
Passwords should be hashed, in contrast to encryption this is a one-way function, that should make it impossible to get back the original password.
Store only the hash-value in the database, and compare against this value for login.
Use a unique salt per password, it can be stored plaintext in the same database field as your hash-value.
Use a slow key-derivation function like Bcrypt, to prevent brute-force attacks.
It's recommended to use a well established library like phpass to build the hashes. For further reading have a look at this tutorial.
I'm developing a web service where users must login. I will store user data in an SQL database and input/output via PHP. But I don't want to store it openly. How do I encrypt the passwords in PHP so only those who knows the password can unlock it?
I know services like phpBB uses some sort of hiding/encryption on stored passwords.
You need to salt and hash the password, using an appropriately secure algorithm.
PHP's mhash has appropriate hashing functions
A full example here on SO
The easiest way to get your password storage scheme secure is by using a standard library.
Because security tends to be a lot more complicated and with more invisible screw up possibilities than most programmers could tackle alone, using a standard library is almost always easiest and most secure (if not the only) available option.
See this answer for more info
You probably want to hash the password - not encrypt it. Check out SHA-1. Hashing means that you cannot retrieve the original data as you can with encryption. Instead what you do is hash the users input and compare it to the hash in the database to see if they've got the right password. Doing this increases security as if your database was ever compromised - a bunch of hashes are useless.
Well, you shouldn't encrypt them with MD5 (which is not really secured, most hackers have conversion tables).
Hence, you can hash it with SHA1 (which is usually used).
If you want more security, you can add more salt which is a key you can add like this (just an example, usually used) :
salt+sha1(salt+pass)
This combination can be used with many language.
Hash passwords in SHA-1 (sha1 php inbuilt function) with several recursions of salting (same code in the answers above, only loop through several times). This should be sufficient protection, so even if the intruders somehow get their hands on the hashes, they shouldn't be able to crack them...
Save an MD5 hash and to make it more secure, add a salt.
There is the possibility to hash passwords (preferably with a salt):
$salt = random_string($length = 5);
$hash = $salt . sha1($salt . $password);
Or store encrypted (only if your MySQL connection is SSL secured):
INSERT INTO `user` (`user`,`pass`) VALUES("username",ENCRYPT("password","secretkey"))
I have read about using MySQL AES_ENCRYPT/AES_DECRYPT (two-way encryption) is less secure than using PHP - hash() (one-way encryption).
http://bytes.com/topic/php/answers/831748-how-use-aes_encrypt-aes_decrypt
Is it true that it is more secure that 'Rather than send the User his password, simply send him a link that he can click on to reset his password, instead.'?
And on top of that, if I am using MySQL AES_ENCRYPT/AES_DECRYPT (which I quite keen on...), how do I define the key which can be accepted by MySQL? for instance, is the length of the key important? or can I simple use '123123#123123' as my key?
thanks!
There is a fundamental difference between the two concepts, hashing and encryption:
Encryption can be reversed, hashing can't (at least that's the idea).
If a malicious user gains access to the passwords in a database and knows the key you used to encrypt them, they will be able to recover said passwords. If they are hashed, they won't be able to do that.
That's why passwords should be always be hashed (and salted), never encrypted.
for instance, is the length of the key important? or can I simple use '123123#123123' as my key?
AFAIK MySQL's AES_ENCRYPT can take keys of arbitrary length; but obviously shorter keys will make it easier for an attacker to bruteforce it (ie: try all possible combinations)
Two way encryption is inherently less secure because the real data is stored somewhere. That is, you have a password "hello." Then you hash it, you get 5d41402abc4b2a76b9719d911017c592. This is meaningless to a normal person and they will not know how to decrypt it without knowing the correct encryption algorithm. They cannot use this either because only the original password is used. You check a password by hashing it and comparing it to the hash (also stored). 5d41402abc4b2a76b9719d911017c592 hashed is 69a329523ce1ec88bf63061863d9cb14, so they don't match. Even if a user knows the hashed password, he can't get anything out of it.
So you can store the encrypted data, but if you decrypt it when you are pulling it out then anyone can use it.
The security of sending a user a link compared to giving them the password is a different issue. If you email the password, it is printed out in plain text for all to see (and use). Giving them a link to allow them to input a new password means no one will see it which is a bit more secure, but if someone committing fraud has access to that link anyway it is going to cause problems.
About AES, I can't find out too much on it at a glance, but it looks like it doesn't matter what you encrypt. So if you use AES_DECRYPT(AES_ENCRYPT('x', 'b'), 'b'); it will return 'x'. You have to keep track of the key.
If you are storing passwords on your server with symmetric encryption, you have to decode the stored password to test it against a user-submitted password. That means the key also has to be stored on the server. Which means anyone who compromises your webapp can retrieve and decrypt every user's password. (And use them to compromise other accounts where the user has used the same password.)
Hashing a password means that you can't leak the password to an attacker because you don't even know what it is yourself. You can still check whether a submitted password is the same as the original password by hashing it using the same algorithm and salt, so you can still tell whether a submitted password is right or wrong, without having to know what the password is.
Using hashed passwords does mean you can't tell the user what their password was in a ‘recover password’ option. But you don't really want to do that anyway, especially over an insecure mechanism like e-mail. One-time, time-limited reset-password links serve the same purpose with less potential damage.
For passwords, one-way hashes are almost always the way to go. One-way hashes mean that there is far less likelihood that anyone but the user would be able to know their password.
If you choose the one-way route, then you'll need to set up a password reset method. If this is done correctly, it should be fairly secure for most purposes. To gain better security, you can add things like security questions (e.g., "What is your favorite color?") that the user would have to answer before receiving a password reset link in an email.
As for keys for AES_ENCRYPT/DECRYPT-- MySQL will accept variable lengths for the key parameter to the functions, but it will use a 128-bit key regardless, so it's to your advantage to pass at least 128 bits' worth.
One-way encryption means you can only encrypt. (For example, you encrypt a password and store the result. Whenever a user authenticates, you encrypt what the user enters and compare. There is no need for a decrypt function in such a scenario.)
Two-way encryption means, there is both an encrypt and decrypt function available. In PHP, that is accomplished through the mcrypt_encrypt() and mcrypt_decrypt() functions.
An update! mcrypt is deprecated in PHP 7.1 and removed in 7.2. See OpenSSL or Sodium instead for encrypt and decrypt functions.