Cryptographic hash functions and a PBKDF2 usage example

feminist python meetup [0x08]

 

jackie / Andrea Ida Malkah Klaura <jackie@diebin.at>

12th March 2019
CodeFactory

Slides: https://tantemalkah.at/2019/fempy_hashing

What you need to know before:

  • it's very brief, of course, there is lots more!
  • should give you some idea
  • happy to go into detail afterwards
  • i'm not a cryptographer, but educated in ITsec
  • Wikipedia always knows more: Cryptographic hash function

What it's for

A hash function maps data

  • from arbitrary length
  • to fixed length


Source: Wikimedia Commons (Public Domain)

A cryptographic hash function

is a hash function that

  • is deterministic
  • is quick to compute one way
  • is infeasible to compute the other way
  • is therefore often called a one-way function
  • changes extensively, even if the input only has small changes
  • makes it infeasible to find two different messages with the same hash
Source: Wikimedia Commons (Public Domain)

Use cases:

  • Verifying file & message integrity
  • Verifying and creating digital signatures
  • Password verification
  • Proof-of-Work (you know, the blockchain thingy)
  • File identification (e.g. in git, mercurial or for file sharing with magnet links)

How it works

a very simple one-way function

M % K = H

              e.g.:
23 % 5 = 3 42523 % 5 = 3 42 % 5 = 2 23542 % 5 = 2

How to do it the cryptographic way?

Some examples:

Remember: MD5 and SHA-1 are already broken

Even better ways (for password hashing):

Using key-derivation functions

  • not originally developd for password hashing
  • but fulfill all characteristics for password hashing functions
  • and often better protect against brute-force attacks
  • examples (in order of increasing security):

Usage example

PBKDF2

Getting the module

Let's install:

              
                $ pip3 install pbkdf2
              
            

Let's get derived!

              
                #!/usr/bin/python3

                from pbkdf2 import PBKDF2
                import os
                import base64

                passphrase = "This is my aweseomest most annoyingly long passphrase with no extra security features whatsoever!"

                salt = os.urandom(8)
                derivedKey = PBKDF2(passphrase, salt).read(32)

                print("The derived key is:")
                print(base64.b64encode(derivedKey))
              
            

Using it for encryption

              
                #!/usr/bin/python3

                from pbkdf2 import PBKDF2
                from Crypto.Cipher import AES
                from Crypto import Random
                import base64

                passphrase = "This is my aweseomest most annoyingly long passphrase with no extra security features whatsoever!"

                salt = Random.new().read(8)
                derivedKey = PBKDF2(passphrase, salt).read(32)

                initialisationVector = Random.new().read(16)
                cipher = AES.new(derivedKey, AES.MODE_CBC, initialisationVector)

                # Now lets encipher something
                encryptedMessage = base64.b64encode(cipher.encrypt("Hey there! It's nothing important, still secret!"))

                print("The encrypted message is:")
                print(encryptedMessage)
              
            

Using it for password hashing

              
                #!/usr/bin/python3

                from pbkdf2 import crypt

                passphrase = "This is my aweseomest most annoyingly long passphrase with no extra security features whatsoever!"
                otherPass = "ladida_so_funny"

                print("The crypted passphrase:")
                print(crypt(passphrase))

                print("The crypted other passphrase (with default 400 iterations):")
                print(crypt(otherPass))

                print("The crypted other passphrase, but with 500 iterations")
                print(crypt(otherPass, iterations=500))

                print("The crypted other passphrase, but with 1024 iterations")
                print(crypt(otherPass, iterations=1024))

                print("The crypted other passphrase, but with 4096 iterations")
                print(crypt(otherPass, iterations=4096))
              
            

What you have to remember:

#!

Not everything that looks shiny ...

... shines when it comes to security

Some guidlines:

thx

Questions?

or Answers?

 

These slides:
https://tantemalkah.at/2019/fempy_hashing

E-Mail:
jackie@diebin.at