Hashing Passwords – Python Cryptography Examples
Tags: cryptography, passwords, programming, python
Published: 2020-01-29 13:37:35

---
title: Hashing Passwords – Python Cryptography Examples
published: true
date: 2020-01-29 13:36:33 UTC
tags: cryptography,passwords,programming,python
canonical_url: https://qvault.io/2020/01/29/hashing-passwords-python-cryptography-examples/?utm_source=rss&utm_medium=rss&utm_campaign=hashing-passwords-python-cryptography-examples
---

By Lane Wagner – [@wagslane](https://twitter.com/wagslane) on Twitter

![](https://qvault.io/wp-content/uploads/2020/01/python-1024x682.jpeg)

Building a from-scratch server or using a lightweight framework is empowering. With that power comes responsibility, specifically the responsibility to securely store user’s passwords.

* * *

_Not understanding the security implications of password storage can lead to devastating breaches and leaks. If you are building an application and need to store user credentials, learn about hash functions._   
[Click To Tweet](https://twitter.com/intent/tweet?url=https%3A%2F%2Fqvault.io%2F%3Fp%3D690&text=Not%20understanding%20the%20security%20implications%20of%20password%20storage%20can%20lead%20to%20devastating%20breaches%20and%20leaks.%20If%20you%20are%20building%20an%20application%20and%20need%20to%20store%20user%20credentials%2C%20learn%20about%20hash%20functions.%20&via=wagslane&related=wagslane)

* * *

## Can I Store Passwords In Plain Text?

To demonstrate the potential dangers, let us assume we DON’T hash passwords on a fake example website, _LoveMatchingToday_. Inevitably when a hacker or disgruntled employee obtains access to _LoveMatchingToday’s_ database, they will download all the usernames and passwords:

> user.one@gmail.com – somePa$$wordHere

> user.two@hotmail.com – otherPlainTextPass

Now the attacker can go to other websites, and because a majority of people reuse passwords on different websites, they can hack other systems.

## Solution – Hashing

![](https://qvault.io/wp-content/uploads/2020/01/hash-brown-potatoes-gt-18-56a8bd875f9b58b7d0f4b85c.jpg)

A [hash function](https://qvault.io/2020/01/01/very-basic-intro-to-hash-functions-sha-256-md-5-etc/) (or more specifically in our case, a [key derivation function](https://qvault.io/2019/12/30/very-basic-intro-to-key-derivation-functions-argon2-scrypt-etc/)) deterministically creates a strong key from a password. Because hashes are one-way, the attacker can’t re-create the plaintext password from the hash. Now the attacker would find something like this in the database:

> user.one@gmail.com – cab864878af008fbc550087940ffacdb79a7f82201725e3350e25d6cfbdd4255

> user.two@hotmail.com – 42a7fd2b639d18b3aba5db8504d4530f1f1ab58ab9615414b7629d6ec5c157b8

They won’t be able to use the hash to log in on other systems because they don’t have access to the original password.

In Python, [Bcrypt](https://pypi.org/project/bcrypt/) is a strong key derivation function that can be used in production systems:

```
import bcrypt
bcrypt.hashpw('userPlainTextPassword'.encode(), bcrypt.gensalt())
```

## Rainbow Tables and Salts

![](https://qvault.io/wp-content/uploads/2020/01/rainbow.jpg)

You may have wondered in the above code snippet what the _gensalt()_ function does. If we were to hash passwords without salts, an attacker could do a [rainbow table](https://en.wikipedia.org/wiki/Rainbow_table) attack in order to find the original plain text.

> A salt is a random string of data hashed alongside a password to keep the hash result unique. **Salts should be recreated** each time a new password is saved, and the salt is stored alongside the hashed result so that it can be used again for comparison. **Libraries like bcrypt are smart enough to store the salt IN the resulting string** so that developers don’t need to do the extra work.

For example, let’s say that _LoveMatchingToday_ wisened up and started hashing passwords, but didn’t include unique salts. An attacker could have a precomputed table of hashes:

> aab864878af008fbc550087940ffacdb79a7f82201725e3350e25d6cfbdd425f = password123

> afg3683232297323f2f0087940ffacdb79a7f8284723732350e25d6cfbdd4cccc = shadowTheHedgehog1234

They could then check each hash they find and see if a hash matches an entry in their table. If so, they can effectively “reverse” the hash and learn the original plaintext.

For this reason, we need to salt passwords. Luckily Bcrypt handles salting automagically. For the sake of learning, however, let’s assume they didn’t. If they didn’t, our pseudocode would look something like this:

```
# Save new password
salt = creatRandomSalt()
hashedPassword = hash(newPassword.concat(salt))
database.save(hashedPassword, salt)

# Check password
hashedPassword, salt = database.GetUserCredentals()
passwordInput = userInput
if hash(passwordInput.concat(salt)) == hashedPassword:
  login()
else:
  failure()
```

However, since Bcrypt stores the salt automatically with the hashed result in the “{salt}{hashed}” format, we can just use the following code:

```
import bcrypt

# password = userInput
hashAndSalt = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
# save "hashAndSalt" in data base

# To check:
# password = userInput
valid = bcrypt.checkpw(password.encode(), hashAndSalt)
```

## Thanks For Reading

If you have questions hit me up on twitter!

Lane on Twitter: [@wagslane](https://twitter.com/wagslane)

Lane on Dev.to: [wagslane](https://dev.to/wagslane)

Download Qvault: [https://qvault.io](https://qvault.io/)

The post [Hashing Passwords – Python Cryptography Examples](https://qvault.io/2020/01/29/hashing-passwords-python-cryptography-examples/) appeared first on [Qvault](https://qvault.io).