All code examples available at: https://github.com/glynrob/encryption
Hashing is an important part of the storing the passwords of your users in your database.
You do not need to know or be able to look up the password a user used. Instead you want to be able to validate that the password is correct then let them continue on your website/app.
So how do you do this?
In all programming languages there are hashing functions available to you that do this.
This is not encryption, as hashing is only be made one way, it can not be reversed to get the original password.
If your database was ever hacked and copied by a third party (it has happened to very big companies so could easily happen to you too) then the hash password you stored will not show the passwords of your users.
Many users use the same password on all websites which means that attacker can now try other websites with the same credentials to gain access.
Salt is a term used when hashing data which simply means adding some data.
So if your password was monkey123, when you hash this password you actually hash monkey123SALTVAL
The salt value should be unqiue to the user also so you DO NOT USE THE SAME SALT value for all users.
If the same salt was used then it would be easier for the attacker to create its own rainbow table (try all password variations) to find the original unhashed password.
Therefore you need to now save 2 items of data for this user.
- Hashed password
- Salt value
This salt value should be random and not just the unix time stamp of the server when it was created. My examples use methods like openssl_random_pseudo_bytes but other options like mcrypt_create_iv are just as suitable.
The more random and longer the string is, the better.
There are many different hashing functions available so I choose 3 to sample.
- MD5 – Now very weak so do not use
- SHA1 – Stronger but still not suitable
- SHA512 – Strong and recommended
What you aim to do is choose a function that takes awhile to generate the output.
You want to do this to avoid possible rainbow tables, the longer it takes to get 1 result the longer it will take an attacker for each possible password.
You could hash the value 100 times to make the generation time longer but keep an eye on your server if many people are logging in at the same time.
You save the salt value for that user and the hashed value when they create their account.
Next time they try to login you generate a hash using the same method but with the saved salt value and if the hash matches, then the password was correct.
Public Key Encryption
Public Key Encryption is used to encrypt data from one point and allow it to be decrypted in another using different keys.
This is used for saving sensitive users data in a database, or passing information from one server to another.
This means a provider can have his own private key which he never shares with anyone, but provides multiple public keys to other which allows them to encrypt the data to be sent to him. Only the provider with the private key can decrypt this data.
There are other encryption methods available, but my examples use openSSL
DO NOT USE MY PUBLIC KEY except for testing. This private key is public so anyone can decrypt any data you send using this.
To generate your own private and public keys you can use:
# private key
openssl genrsa -out mykey.pem 2048
# public key
openssl rsa -in mykey.pem -pubout -out mykey.pub
Puttygen or one of the other software providers
If you run the examples I provided for PHP and Python you should see the following output.
From this example you see a string encrypted which can then be sent anywhere, then it is decrypted back with the private key.
Example function PHP:
Example function Python:
It really is as easy as that to encrypt and decrypt data.
Just ensure that the private key is only available at the locations where it is required.