Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Basic applied cryptography - saving passwords

Basic applied cryptography - saving passwords

Focuses on how to properly save a password in a database. Talks about hash functions, saving passwords, symmetric/asymmetric encryption and randomness.

I suspect people will take issue with me lumping all pre-computer tables together under the moniker of "rainbow table", but I really wanted to simplify things as much as possible. But please be aware that where it says rainbow table you can find and replace with "a pre-computed table, which was built with the intention of cracking passwords".

Avatar for Chris DiLorenzo

Chris DiLorenzo

January 27, 2018

Other Decks in Programming

Transcript

  1. Goals 1. Never, ever save passwords in plaintext in a

    database. 2. Know how to store passwords in a database. 3. Understand the difference between a strong key and a weak key. 4. Understand why randomness is important for cryptography.
  2. Glossary and Assignments • https://gist.github.com/chrisdl • Look for crypto_glossary.md •

    Also open: • hashFunctionAssignment.js • savePasswordAssignment.js • symmetricEncryptionAssignment.js
  3. Master Plan • Hash Functions • DIY: Saving passwords in

    databases. • Symmetric encryption (1 secret key) • Asymmetric encryption (public and private key) • Randomness • Recap
  4. • Aka one-way-function, aka non-reversible. • Predictable output. (Same input

    gives same output) • Common uses: hashing passwords, verifying message integrity etc. • Common implementations: SHA1, SHA2 (SHA256, and more), MD5... • In terminal: $> openssl list-message-digest-algorithms Hash functions SHA256("hello world") OUTPUT (hex): b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
  5. Password saving Level 1: They are attacking our webserver (~1000

    /s) Level 2: They stole our DB (10k - 100k /s) Level 3: Insider threat
  6. Password saving But what about comparing? User Input Plaintext Password

    Hash Function Password Hash Database Get User Password Hash Password Hash
  7. • Already way better than saving "123456" to the database

    directly. • Problem 1: It's too damn fast. Password saving SHA256("123456") OUTPUT (hex): 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
  8. • Cool now it's slower. • Problem 2: Someone could

    generate a rainbow table (other tables include lookup tables and reverse-lookup tables, but I am going to call them all rainbow tables because it has the catchiest name. Come at me bro.) Password saving passwordHash = '123456'; Loop 70 000 times: passwordHash = SHA256(passwordHash)
  9. • Using a rainbow table they will crack multiple users

    passwords very quickly. Password saving Try: 56708be877dd...3ccc9ba45361 - 123456789 cd25fc5f18d6...d447ff4be9be - 123456 74e1f160df56...b31572f8b3fb - qwerty
 Real Password: cd25fc5f18d6...d447ff4be9be
  10. • Solution: Salt • Public random string of characters that

    we append to the password. • Vastly increases the size of the rainbow table. • Generate a new unique (CSPRNG) salt for every new password! • Rule of thumb: Salt should be as long as the passwordHash Password saving salt = generate 64 random characters passwordHash = '123456' Loop 70k times { passwordHash = SHA256(passwordHash + salt) }
  11. Password saving // Without SALT // We can try each

    passwordAttempt in our rainbow table on // a users passwordHash. Table size = 1 rainbow table. For userPasswordHash in stolen database { For passwordAttempt in rainbow table { If (userPasswordHash === passwordAttempt) return $$$; } } // With SALT // We need to tailor each passwordAttempt to use the salt of the // user we are currently trying crack. // Table Size = rainbow table * nr of users. For (userPasswordHash, usersUniqueSalt) in stolen database { Table = getTable(usersUniqueSalt) For passwordAttempt in Table { If (userPasswordHash === passwordAttempt) return $$$; } }
  12. Password saving What if we don't create a unique salt

    per password? (This is a mistake that surprisingly many competent developers make)
  13. Password saving What if we don't create a unique salt

    per password? (This is a mistake that surprisingly many competent developers make) • Cracker can simply generate the rainbow table but using the salt all the users share. Since the salt does NOT change for each user, the rainbow table size is no longer multiplied by the number of users.
  14. Symmetric encryption 1. Reversible: what can be encrypted can be

    decrypted using the same key. 2. Sharing the key is an issue. 3. Key generation is important (not really a human generated password). 4. The information content does not change. Or at least it is not less, because if it was less than we wouldn't be able to decrypt.
  15. Symmetric encryption Briefly, on blocks and padding Block size of

    8 bytes 1 block: DD DD DD DD DD DD DD DD Add Padding! 1 block: DD DD DD DD DD DD 00 00 (add zeroes until you have 1 block). Better way (PKCS7): 1 block: DD DD DD DD DD 02 02 02 (add the number of padding as the padding)
  16. Randomness • RNG = Random Number Generator • PRNG =

    Pseudo Random Number Generator • CSPRNG = Cryptographically Secure Pseudo Random Number Generator
  17. Randomness Generating Randomness If you are generating something random and

    it is very short The odds of generating the same thing again are very high.
  18. Randomness Generating Randomness 0 0 0 1 1 0 1

    1 For example: worst password of all time! 2 characters and It's binary! If you are generating something random and it is very short The odds of generating the same thing again are very high.
  19. Randomness Key Space For Smarties (math incoming) AES256 == AES

    with a 256-bit key 1 byte is 8 bits 256 bits is 32 bytes (256/8) 1 0 = 1 bit Key space: 2
  20. Randomness Key Space For Smarties (math incoming) AES256 == AES

    with a 256-bit key 1 byte is 8 bits 256 bits is 32 bytes (256/8) 1 0 = 1 bit 0 0 0 1 1 0 1 1 Key space: 2 = 2 bits Key space: 4
  21. Randomness Key Space For Smarties (math incoming) AES256 == AES

    with a 256-bit key 1 byte is 8 bits 256 bits is 32 bytes (256/8) 1 0 = 1 bit 0 0 0 1 1 0 1 1 Key space: 2 = 2 bits Key space: 4 0 0 0 0 0 1 0 1 0 1 0 0 0 1 1 1 0 1 1 1 0 1 1 1 = 3 bits Key space: 8
  22. Randomness 1 bit 2 bits 3 bits 4 bits Ks

    = 2 Ks = 4 Ks = 8 Ks = ? Q1: What is the key space for 4 bits? Q2: What is the general equation describing the key space in bits?
  23. Randomness AES256 could be achieved with this key IFF it

    was generated using a CSPRNG! 11111011 00110111 11100101 00110010 01111100 10010100 01000101 11110100 00101001 10000011 11111000 11101010 01001000 11101111 10100001 10111110 10101100 10111100 01011101 01111010 11110110 00011000 00100110 11010100 11011001 00010101 00001101 11101011 01101010 00100011 00011010 00000000 (256 bits, 32 bytes) Key space is 2^256 aka ~10^77. That is a lot of possible keys!
  24. Randomness You will often see keys represented in hex, thats

    because you get away with just 2 characters for every 8 in base 2. Base 2: 11111011 = 1 byte = 2^8 Base 16 (hex): FB = 1 byte = 2^8 = 16^2 16 possible values (0123456789ABCDEF) = 2^4 aka 16^1 2^4*2^4 = 2^8 = 16^2 = 256 bits aka 1 byte.
  25. Randomness • The base doesn't matter, what matters is the

    amount of randomness, complexity, entropy. • For a lot of ciphers the key being provided is THE deciding factor as to how secure it really is. 11111011 00110111 11100101 00110010 01111100 10010100 01000101 11110100 00101001 10000011 11111000 11101010 01001000 11101111 10100001 10111110 10101100 10111100 01011101 01111010 11110110 00011000 00100110 11010100 11011001 00010101 00001101 11101011 01101010 00100011 00011010 00000000 FB 37 E5 32 7C 94 45 F4 29 83 F8 EA 48 EF A1 BE AC BC 5D 7A F6 18 26 D4 D9 15 0D EB 6A 23 1A 00 = (base 2) (base 16)
  26. Randomness 11111011 00110111 11100101 00110010 01111100 10010100 01000101 11110100 00101001

    10000011 11111000 11101010 01001000 11101111 10100001 10111110 10101100 10111100 01011101 01111010 11110110 00011000 00100110 11010100 11011001 00010101 00001101 11101011 01101010 00100011 00011010 00000000 FB 37 E5 32 7C 94 45 F4 29 83 F8 EA 48 EF A1 BE AC BC 5D 7A F6 18 26 D4 D9 15 0D EB 6A 23 1A 00 = = ? (base 2) (base 16)
  27. Randomness 251 55 229 50 124 148 69 244 41

    131 248 234 72 239 161 190 172 188 93 122 246 24 38 212 217 21 13 235 106 35 26 0 11111011 00110111 11100101 00110010 01111100 10010100 01000101 11110100 00101001 10000011 11111000 11101010 01001000 11101111 10100001 10111110 10101100 10111100 01011101 01111010 11110110 00011000 00100110 11010100 11011001 00010101 00001101 11101011 01101010 00100011 00011010 00000000 FB 37 E5 32 7C 94 45 F4 29 83 F8 EA 48 EF A1 BE AC BC 5D 7A F6 18 26 D4 D9 15 0D EB 6A 23 1A 00 = = (base 2) (base 16) (base 256)
  28. Randomness • Level 1: 8 uppercase/lowercase letters (abcdefghijklmnopqrstuvwxyz) (52 letters)

    • Level 2: Add a number. (0123456789) (10 digits) • Level 3: Add a symbol (X symbols). • TL;DR; They are trying to offload stronger key generation on the end user. Website password example:
  29. • Never save a password in plaintext. • Hash functions

    are one-directional. • Symmetric/Asymmetric encryption can be decrypted (two-directional). • "Good" Randomness is super important when it comes to cryptography. • Sometimes you are giving away important information to an attacker in a non- intuitive way. • It is very hard for a developer to save a user from being breached if they have a bad password.