Python Password Hashing

Python Password Hashing

  1. Salt and Hash Password With bcrypt Library in Python
  2. Hash a Password Using hashlib Library

We will learn about password hashing and how to encrypt a salt and hash password with a third-party library called bcrypt. We also look at different hashing algorithms from the hashlib library in Python.

Salt and Hash Password With bcrypt Library in Python

Hashing is the process of taking a string and turning it into a seemingly random string of a fixed length, and that process is irreversible. It is a one-way function, so you cannot return the hash to its original string like encryption, where you can encrypt a message and then decrypt it.

Hashing is used in user management; for example, if we have some database breach or lose data or someone hacks our system when we use a plaintext password. Hashing gives us some layer of protection; however, the hashed password cannot easily be cracked if we maintain it properly.

In this section, we will see how to work with hashed passwords using the bcrypt module; let’s go ahead and jump into the code. We are going to use a third-party library called bcrypt, which is a hashing algorithm.

bcrypt is a reliable, robust, and recommended algorithm for hashing passwords; it gives us some nice and simple-to-use functions that let us get things done quickly.

First, we will install this library by using the following command.

pip install bcrypt

Now we need to import bcrypt, create a password, and store it in a variable, and the password must be a byte string. To hash this password, we will create a new variable called hashed_pswd and call the hashpw() method from bcrypt.

It takes two arguments; the first is a password, and the second is something called gensalt(), randomly generating a number or a salt and hash password.

import bcrypt

My_pswd = b"Mypassword111"

hashed_pswd = bcrypt.hashpw(My_pswd, bcrypt.gensalt())
print(hashed_pswd)

Output:

b'$2b$12$KEW01pYNDc3ee9U0wZpmgOBpUvvjkig/qxs593hGh/aZ2AvvGTyWu'

Hash a Password Using hashlib Library

This section will use the hashlib library to create a salt and hashed password. If you pass secure data like passwords and stuff from one location to another, it is a good idea to ensure that someone cannot read it.

There are two types of things that you can do when you want to hide something or make it unreadable for the user. The first is hashing, and the second is encryption; encryption is mostly not used in passwords.

If we want to transfer files from our computer to another or send a file, then we use encryption. But, if we want to check whether the password is correct or not or to store passwords in our server, then mostly hashing is used.

The best thing about the hashlib library is that we do not need to install anything; it comes with Python 3 or a newer version. After importing hashlib, we will create an object called MD5_Algo and call md5() from hashlib.

md5 is just a kind of hashing algorithm, md stands for message-digest, and 5 is the version. Now we need the string we want to convert plaintext into hashing, and for this, we call the update() method and write the string we want to hash.

Then inside the print() function, we call the hexdigest() method; after converting the strain to actual md5, it converts into a hex form.

import hashlib

MD5_Algo=hashlib.md5()
MD5_Algo.update('hello')
print(MD5_Algo.hexdigest())

This piece of code throws an error (Unicode objects must be encoded before hashing), and in the above section, we already discussed that we need to convert a string into bytes.

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_4064/2416014515.py in <module>
      2
      3 MD5_Algo=hashlib.md5()
----> 4 MD5_Algo.update('hello')
      5 print(MD5_Algo.hexdigest())

TypeError: Unicode-objects must be encoded before hashing

After converting the string into bytes, we see it gives us an md5 encrypted hashed password.

import hashlib

MD5_Algo=hashlib.md5()
MD5_Algo.update(b'hello')
print(MD5_Algo.hexdigest())

Output:

5d41402abc4b2a76b9719d911017c592

hashlib.sha512()

There are also other kinds of encrypted hash; let’s find out what kind of hashing stuff is actually inside Python. We can print out available algorithms using the algorithms_available attribute.

print(hashlib.algorithms_available)

Output:

{'md4', 'md5', 'shake_256', 'shake_128', 'sha512_224', 'md5-sha1', 'sha224', 'sha3_512', 'sha1', 'sha3_384', 'sha512', 'sha3_224', 'sha512_256', 'sha384', 'sha256', 'blake2b', 'sha3_256', 'blake2s', 'ripemd160', 'whirlpool', 'sm3', 'mdc2'}

As we can see, there are a lot of cool algorithms, and obviously, all of these objects have the same sort of structure, they will have the same functions and variables, but it is just a different algorithm.

sha512 is the one we will use and pass in a string; after that, we use hexdigest() to that string, which will be hashed.

import hashlib

MD5_Algo=hashlib.sha512(b'hello')
print(MD5_Algo.hexdigest())

When we run this code, we get a long mass of characters.

9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043

sha512 is stronger and kind of better than sha1; it all depends on the scenario you determine as better or best in your circumstances.

Salting and Hashing

The problem with these kinds of old algorithms is that they can be brute-forced or reverse-engineered, and it is not that safe because everyone can decrypt this encrypted hash easily. Our encrypted hash is hello; what if we do a dictionary attack and decrypt it from the sha512 dictionary?

sha512

The downfall of sha512 is that many people use their passwords on Facebook or other applications; usually, they use their birthdays which have already been reversed and looked at in sha512, so that is why it is not a safe way.

One of the safest ways is salting; salting adds some character in front of your original string. Let’s say if we add "a" in front of "hello", we have added the character "a" as salt in front of our original string.

hashlib.sha512(b'helloa')

Now we have encrypted this hash with this extra salt which is why it will be very difficult for hackers and other people who try to figure out how to decrypt the hash, so that is where the salt comes in.

hashlib.pbkdf2_hmac()

In Python, the hashlib library has a function that is a little bit slow but a pretty good function called pbkdf2_hmac(). We will be using this function and the second library is actually for converting the binary to ASCII characters.

The pbkdf2_hmac() requires a couple of parameters; the first parameter is the name of the algorithm we will use, so we are using sha512 in this case. The next one is the password or the text we want to hash; in this case, it will be "hello".

The next one is called salt, the salt will be added to this password, and then they will be encrypted using sha512. And the last one is the number of iterations; if we do this iteration a hundred thousand times, then it is going to be very difficult to find it to decrypt.

In the last line of code, we convert the encrypted hash to an ASCII character using the hexlify() method from the binascii library.

import hashlib, binascii

Enc_Salt = hashlib.pbkdf2_hmac('sha512',b'hello',b'a',100000)
print(binascii.hexlify(Enc_Salt))

Output:

b'40b5957a2d2f5aebcdd878a04e644215d4f3aba3f11c00a1f24e75f8ea2efa11611b2a923a9050832cb768a3a3ad282011cab524b741d392c664b8efbb5f389f'

Now we can see the sha512 dictionary cannot decrypt.

sha512 cannot decrypt

Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn