Python Hashing and Encryption

The Basics

What is hashing?

Hashing is an algorithm that is used to transform data of any length into a fixed length and is only one way. What this means is that you there is not a purpose to reverse hashing. The hashed the passwords would live hashed in a password database for the rest of their lives. When a user wants to authenticate, the password gets hashed and then the hashes are compared to see if they match character for character. There many different hashing algorithms, they different by:

  • length
  • speed

All of which will determine how secure they are.

import hashlib
dude = hashlib.sha256("mypassword").hexdigest()
print(dude)

Output

89e01536ac207279409d4de1e5253e01f4a1769e696db0d6062ca9b8f56767c8

What is Salt or Salting?

Salt is random data, bit/bytes, that is used to make a unique direction for a hash. Instead of just telling something to hash this password, the salt gives it a more unique one off hash that will give the hackers one more layer to dig through.

import hashlib
import string
import random

def id_generator(size=6, chars=string.ascii_uppercase + string.digits + string.ascii_lowercase):
   return ''.join(random.choice(chars) for _ in range(size))

salt = id_generator(25)
dude = hashlib.sha256("mypassword" + salt).hexdigest()
print(dude)

Output

a998c90881afb36166b2b7c18c35c744c62b72cffb8656805952175a2b727165

What is encryption?

It’s like hashing, but it’s two way. If a person or computer wants to read or digest something in plain text but needs to be encrypted to safety send it to the recieptient, in order to do this, a key is needed. A key is used to encrypt and decrypt the password, so it is important to save it in a secure location. For example, do not leave it on a shared drive that everyone has access to.

For example, an encrypted email is:

  • typed up in clear text
  • encrypted
  • sent
  • decrypted
  • read in clear text

What are the recommended Hashing Methods?

Important, it’s recommended to alway use a hash plus salt. Hackers have many ways to calculate what the stored clear text value is:

  • rainbow tables
  • reverse lookup tables
  • lookup tables

All of these methods:

  • hash a clear text password
  • evaluate if it matches that hash they found/hacked
  • if it matches, they now know you password

In other words, they can perform a brute force attack on a hash with out having to attempt to authenticate. Once they have found and hash/password match, they will now know your password.

If the password or value is salted or has extra bits added, then even if they are able to brute force hack it (which is unlikely), they will only have a clear text value that is useless.

What is Key Stretching?

Key Stretching is a method of creating a key by giving it a unique length and some extra random bits via salt.

What are the recommended Encryption Methods?

Python Modules

Secure Hashing Python Modules

bcrypt – The current defacto for hashing passwords. Keys can also be generated as well. It is still new (2012) so it is not widely adopted.

PBKDF2 – More of a Key Hashing, but can be used to hash passwords. The key is needed for encryption.

scrypt – A replacement for bcrypt and PDKDF2. You can install scrypt here

Secure Encryption Python Modules

bcrypt and scrypt both use AES to encrypt, but its really just one way.

Use pycrypto

>>> from Crypto.Cipher import AES
>>> obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
>>> message = "The answer is no"
>>> ciphertext = obj.encrypt(message)
>>> ciphertext
'\xd6\x83\x8dd!VT\x92\xaa`A\x05\xe0\x9b\x8b\xf1'
>>> obj2 = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
>>> obj2.decrypt(ciphertext)
'The answer is no'

Hacky way to just use base64 with “Salting” or “Padding”

Base64 Without Salting

password = 'mypassword12345'
hashed = base64.b64encode(password)
print(password)
print(hashed)
print(base64.b64decode(hashed))

Output

mypassword12345
bXlwYXNzd29yZDEyMzQ1
mypassword12345

Base64 With Salting

import string
import random
def id_generator(size=6, chars=string.ascii_uppercase + string.digits + string.ascii_lowercase):
   return ''.join(random.choice(chars) for _ in range(size))

# Save this somewhere so you know what to strip out
salt = id_generator(25)
password = 'mypassword12345'
hashed = base64.b64encode(password + salt)

print(salt)
print(password)
print(hashed)
print(base64.b64decode(hashed))

Output

SUVCo6V2JUo0dITspOjR0N6OF
mypassword12345
bXlwYXNzd29yZDEyMzQ1U1VWQ282VjJKVW8wZElUc3BPalIwTjZPRg==
mypassword12345SUVCo6V2JUo0dITspOjR0N6OF

References

Salted Password Hashing – Doing it Right

I need to securely store a username and password in Python, what are my options?

The scrypt key derivation function

An example usage of an encryption algorithm (AES, in this case) is

About Daniel Fredrick

Technology enthusiast, Programmer, Network Engineer CCIE# 17094

View all posts by Daniel Fredrick →

3 Comments on “Python Hashing and Encryption”

  1. Hey Dan,

    Nice breakdown.

    I have pretty much used Bcrypt for every project in the last few years. It is pretty solid. I will checkout out scrypt and see what some of the advantages of that might be.

    Keep posting cool stuff, I hope all is well.

    1. Thanks Shane! Good to hear from you. Scrypt seems good, just a little new. There are some really cool tests that are being done how with this. The neatest feature is being able to specify how long it should take to hash the bytes.

      Hope all is well, posting on wordpress has really helped my brain to be able to focus and provides clarity.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.