I see a lot of confusion between hashes and encryption algorithms and I would like to hear some more expert advice about:
When to use hashes vs encryptions<
A Hash function turns a variable-sized amount of text into a fixed-sized text.
Source: https://en.wikipedia.org/wiki/Hash_function
Hash functions in PHP
A hash turns a string to a hashed string. See below.
HASH:
$str = 'My age is 29';
$hash = hash('sha1', $str);
echo $hash; // OUTPUT: 4d675d9fbefc74a38c89e005f9d776c75d92623e
Passwords are usually stored in their hashed representation instead as readable text. When an end-user wants gain access to an application protected with a password then a password must be given during authentication. When the user submits his password, then the valid authentication system receives the password and hashes this given password. This password hash is compared to the hash known by the system. Access is granted in case of equality.
DEHASH:
SHA1 is a one-way hash. Which means that you can't dehash the hash.
However, you can brute-force the hash. Please see: https://hashkiller.co.uk/sha1-decrypter.aspx.
MD5, is another hash. A MD5 dehasher can be found on this website: https://www.md5online.org/.
To hamper brute-force attacks on hashes a salt can be given.
In php you can use password_hash()
for creating a password hash.
The function password_hash()
automatically creates a salt.
To verify a password on a password hash (with a salt) use password_verify()
.
// Invoke this little script 3 times, and it will give you everytime a new hash
$password = '1234';
$hash = password_hash($password, PASSWORD_DEFAULT);
echo $hash;
// OUTPUT
$2y$10$ADxKiJW/Jn2DZNwpigWZ1ePwQ4il7V0ZB4iPeKj11n.iaDtLrC8bu
$2y$10$H8jRnHDOMsHFMEZdT4Mk4uI4DCW7/YRKjfdcmV3MiA/WdzEvou71u
$2y$10$qhyfIT25jpR63vCGvRbEoewACQZXQJ5glttlb01DmR4ota4L25jaW
One password can be represented by more then one hash.
When you verify the password with different password hashes by using password_verify()
, then the password will be accepted as a valid password.
$password = '1234';
$hash = '$2y$10$ADxKiJW/Jn2DZNwpigWZ1ePwQ4il7V0ZB4iPeKj11n.iaDtLrC8bu';
var_dump( password_verify($password, $hash) );
$hash = '$2y$10$H8jRnHDOMsHFMEZdT4Mk4uI4DCW7/YRKjfdcmV3MiA/WdzEvou71u';
var_dump( password_verify($password, $hash) );
$hash = '$2y$10$qhyfIT25jpR63vCGvRbEoewACQZXQJ5glttlb01DmR4ota4L25jaW';
var_dump( password_verify($password, $hash) );
// OUTPUT
boolean true
boolean true
boolean true
An Encryption function transforms a text into a nonsensical ciphertext by using an encryption key, and vice versa.
Source: https://en.wikipedia.org/wiki/Encryption
Encryption in PHP
Let's dive into some PHP code that handles encryption.
--- The Mcrypt extention ---
ENCRYPT:
$cipher = MCRYPT_RIJNDAEL_128;
$key = 'A_KEY';
$data = 'My age is 29';
$mode = MCRYPT_MODE_ECB;
$encryptedData = mcrypt_encrypt($cipher, $key , $data , $mode);
var_dump($encryptedData);
//OUTPUT:
string '„Ùòyªq³¿ì¼üÀpå' (length=16)
DECRYPT:
$decryptedData = mcrypt_decrypt($cipher, $key , $encryptedData, $mode);
$decryptedData = rtrim($decryptedData, "\0\4"); // Remove the nulls and EOTs at the END
var_dump($decryptedData);
//OUTPUT:
string 'My age is 29' (length=12)
--- The OpenSSL extention ---
The Mcrypt extention was deprecated in 7.1. and removed in php 7.2. The OpenSSL extention should be used in php 7. See the code snippets below:
$key = 'A_KEY';
$data = 'My age is 29';
// ENCRYPT
$encryptedData = openssl_encrypt($data , 'AES-128-CBC', $key, 0, 'IV_init_vector01');
var_dump($encryptedData);
// DECRYPT
$decryptedData = openssl_decrypt($encryptedData, 'AES-128-CBC', $key, 0, 'IV_init_vector01');
var_dump($decryptedData);
//OUTPUT
string '4RJ8+18YkEd7Xk+tAMLz5Q==' (length=24)
string 'My age is 29' (length=12)