Glynrob: Hashing and Public Key Encryption
Glynrob: Hashing and Public Key Encryption
GlynRob
All about code and tech
Home
About Me
Learning + Reading
PHP, PYTHON
Hashing
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
https://glynrob.com/php/hashing-and-public-key-encryption/
1/10
20/11/2014
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.
Hashing functions
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.
PHP Example:
1
2
3
4
5
6
7
8
$md5 = md5($password.$salt);
echo "MD5 = $md5<br />";
$sha1 = sha1($password.$salt);
echo "SHA1 = $sha1<br />";
$sha512 = hash('sha512', $password.$salt);
echo "SHA512 = $sha512<br />";
view raw
Python Example:
1
2
3
md5 = hashlib.md5()
md5.update(password+saltstring)
print 'MD5 = '+md5.hexdigest()
https://glynrob.com/php/hashing-and-public-key-encryption/
2/10
20/11/2014
4
5
6
7
8
9
view raw
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.
Windows:
Puttygen or one of the other software providers
https://www.racf.bnl.gov/docs/authentication/ssh/sshkeygenwin
If you run the examples I provided for PHP and Python you should see the following output.
https://glynrob.com/php/hashing-and-public-key-encryption/
3/10
20/11/2014
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function public_encrypt($plaintext){
$fp=fopen("./mykey.pub","r");
$pub_key=fread($fp,8192);
fclose($fp);
openssl_get_publickey($pub_key);
openssl_public_encrypt($plaintext,$crypttext, $pub_key );
return(base64_encode($crypttext));
}
function private_decrypt($encryptedext){
$fp=fopen("./mykey.pem","r");
$priv_key=fread($fp,8192);
fclose($fp);
$private_key = openssl_get_privatekey($priv_key);
openssl_private_decrypt(base64_decode($encryptedext), $decrypted, $private_key);
return $decrypted;
}
view raw
rsa = RSA.load_pub_key("mykey.pub")
ctxt = rsa.public_encrypt(secretstring, RSA.pkcs1_padding)
encryptedText = ctxt.encode('base64')
print 'Encrypted Text = '+encryptedText
priv = RSA.load_key("mykey.pem")
decodeEncryptedText = encryptedText.decode('base64')
decryptedText = priv.private_decrypt(decodeEncryptedText, RSA.pkcs1_padding)
print 'Decrypted Text = '+decryptedText
view raw
https://glynrob.com/php/hashing-and-public-key-encryption/
4/10
20/11/2014
Share this:
Tags: Hashing
md5
PHP
private key
Minify Javascript
public key
Python
sha1
sha512
Git Cheatsheet
https://glynrob.com/php/hashing-and-public-key-encryption/
5/10
20/11/2014
GlynRob
May 10, 2014 at 8:53 pm
Hi PB,
For what you are trying to do I would use something like Crypto.js.
I have covered this http://glynrob.com/javascript/client-side-hashingand-encryption/
You can view the contents of server side public and private keys in the
command line, but you should never email a private key as this is not a
secure way to share information.
Hope this helps
Navinder
August 7, 2014 at 8:41 pm
Hi, I tried copying and pasting your code to my encrpt.php file and called
the function as
public_encrypt(plain text here);
But it is always showing a blank page. I tried copying and pasting the
entire public key from file but still a blank output.
I am using a MAC.
Can you please suggest what I may be doing wrong? Thank you.
MIke
September 29, 2014 at 8:05 pm
https://glynrob.com/php/hashing-and-public-key-encryption/
6/10
20/11/2014
GlynRob
October 6, 2014 at 6:57 pm
Mike: To encrypt and decrypt on the client side read this other blog post
I did.
http://glynrob.com/javascript/client-side-hashing-and-encryption/
Gavin Hanson
November 11, 2014 at 1:56 am
Hello Glyn
This is a very helpful article however it does not cover how to go about
encrypting long strings.
Taken from php.net discussion about openssl_public_encrypt().
When you encrypt something using an RSA key (whether public or
private), the encrypted value must be smaller than the key (due to the
maths used to do the actual encryption). So if you have a 1024-bit key, in
theory you could encrypt any 1023-bit value (or a 1024-bit value smaller
than the key) with that key.
Is there is best practise work around to this?
GlynRob
November 14, 2014 at 1:46 pm
One way would be to break your content into chunks and encrypt them
separately.
http://phpseclib.sourceforge.net/ does this but you could easily
implement a similar solution yourself.
Another option is to use openssl_seal() and openssl_open(). openssl_seal
generates a random string, encrypts it with RSA and then encrypts the
data youre actually trying to encrypt with RC4 using the random string
as the key.
https://glynrob.com/php/hashing-and-public-key-encryption/
7/10
20/11/2014
Leave a Reply
Your email address will not be published. Required fields are marked *
Name *
Email *
Website
Comment
Post Comment
Search
Find Me
Categories
https://glynrob.com/php/hashing-and-public-key-encryption/
8/10
20/11/2014
Apps (1)
CSS (5)
Database (4)
General (9)
Hardware (3)
Javascript (13)
PHP (6)
Python (2)
Security (6)
Versioning (2)
Ads
Tweets
@markrussinovich Already done :) But on Amazon.co.uk
Last week from Glyn Roberts's Twitter
Archives
November 2014
March 2014
November 2013
October 2013
July 2013
March 2013
February 2013
January 2013
December 2012
November 2012
October 2012
September 2012
July 2012
June 2012
May 2012
March 2012
January 2012
Tags
addons andriod
https://glynrob.com/php/hashing-and-public-key-encryption/
9/10
20/11/2014
Hashing
html html5 interviews java Javascript jobs jQuery lego LESS CSS linux
PHP Python
Raspberry Pi Redis security SVN Symfony templating Versioning virus W3C Web Storage
https://glynrob.com/php/hashing-and-public-key-encryption/
10/10