Pragmatic Crypto #2

D4e1d473a995ef37b3e03e9e6006c3e3?s=47 majek04
March 19, 2013

Pragmatic Crypto #2

D4e1d473a995ef37b3e03e9e6006c3e3?s=128

majek04

March 19, 2013
Tweet

Transcript

  1. Pragmatic crypto #2: hashing Marek Majkowski

  2. DIYOC • “Don't invent your own crypto.”

  3. Last week

  4. PRG 0 1 0 1 1 0 0 1 1

    0 0 1 1 1 0 0 1 1 0 1 f(state) state value
  5. PRG Language Method State size C, Java, VB LCG 32

    Python Mersenne Twister 32 DVD; GSM; Bluetooth LFSR 40 OpenSSL.RAND_bytes unnamed 8192 RC4 1024 Salsa 20 128 or 256 Sosemanuk 128 or 256 • http://spark-university.s3.amazonaws.com/stanford-crypto/slides/02-stream-v2-annotated.pdf • http://src.gnu-darwin.org/src/crypto/openssl/crypto/rand/md_rand.c.html
  6. Entropy • Hardware Random Number Generator • Geiger counter •

    Intel RdRand • /dev/random • /dev/urandom • https://en.wikipedia.org/wiki/Entropy_(computing) • https://en.wikipedia.org/wiki/RdRand • http://en.wikipedia.org/wiki/Hardware_random_number_generator • http://www.ciphergoth.org/crypto/unbiasing/
  7. Real world bug Intention 2014 * 1012 50.8 Constrains 1900

    * 1012 50.7 Weak algo 100% 3.656 * 1012 41.7 Weak algo 75% 1.311 * 1012 40.2 Weak PRNG 4294 * 106 32 Weak seed 86.4 * 106 26 Seed and PRNG 64 * 103 16
  8. Conclusion • Never use built-in “Math.random()” • It’s (almost) always

    predictable • CS-PRG are rarely built-in • Must be seeded with good entropy • Testing entropy sources is hard
  9. Assignments

  10. Assignment #0 [+] Your task is to guess my super

    secure, completely unpredictable password: https://pragmaticcrypto.herokuapp.com/exercise0/ https://github.com/majek/web4crypto
  11. Assignment #1 [ ] This is my PRNG code: def

    _lcg(state): return (1103515245*state + 12345) % (2**31) def lcg_generator(seed): state = seed while True: state = _lcg(state) yield state with open('/dev/urandom', 'rb') as f: seed, = struct.unpack('I', f.read(4)) gen = lcg_generator(seed) [ ] See - my PRNG is initialized using super secure seed! [ ] First value of the PRNG is: 123456 [+] Your task is to predict the second value of my LCG PRNG: https://pragmaticcrypto.herokuapp.com/exercise1/
  12. • http://www.smogon.com/forums/group.php?do=discuss&gmid=1699 Assignment #2* https://pragmaticcrypto.herokuapp.com/exercise2/ [ ] This is my

    PRNG code: def _lcg(state): return (1103515245*state + 12345) % (2**31) def lcg_generator(seed): state = seed while True: state = _lcg(state) yield state with open('/dev/urandom', 'rb') as f: seed, = struct.unpack('I', f.read(4)) gen = lcg_generator(seed) [ ] Second value of the PRNG is: 12345 [+] Your task is to recover the first value of my LCG PRNG:
  13. • http://hg.python.org/cpython/file/3.2/Lib/random.py#l111 Assignment #3 [ ] 29777 seconds ago I

    generated a password. [ ] You will never crack it! [ ] Oh, I used python random module, and I initialized the [ ] seed like python does on some platforms: random.seed(int(time.time() * 256)) [ ] The password was generated like that: secret = ''.join(random.choice(string.ascii_letters) for i in range(12)) [+] Your task is to guess the password: https://pragmaticcrypto.herokuapp.com/exercise3/
  14. ToC • Random numbers • Pseudo Random Generators (PRG) •

    Cryptographically Secure PRG (CS-PRG) • Sources of entropy • Hashing • Traditional hashing • Cryptographically Secure Hashing • Message Authentication Code • Key Derivation Functions • Side Channel Attacks
  15. Hash functions

  16. Hash function def hash(string): return number

  17. Hash table hash(“Tom”) % 6 = 3 hash(“John”) % 6

    = 5 hash(“Sarah”) % 6 = 5 0 1 2 3 4 5 Tom John Sarah X X
  18. Hash table Average Insertion O(1) Deletion O(1) Lookup O(1)

  19. Hash table def hash(string): return 3

  20. Hash table hash(“Tom”) % 6 = 3 hash(“John”) % 6

    = 3 hash(“Sarah”) % 6 = 3 0 1 2 3 4 5 Tom John Sarah X
  21. Hash table Average Worst Insertion O(1) O(n) Deletion O(1) O(n)

    Lookup O(1) O(n) • https://en.wikipedia.org/wiki/Hash_table
  22. Real world bug • CVE-2011-4815

  23. Assignment #4 [ ] I'm an application that memorizes strings.

    [ ] I have a small hash table implemented here: hash_table = [[] for i in range(1023)] [ ] I save the string like that: hash, = struct.unpack('I', hashlib.md5(string.encode('ascii')).digest()[:4]) bucket = hash_table[hash % 1023] if string not in bucket: bucket.append( string ) [ ] It's using md5! It's super secure for hash table! [ ] BTW, I also clean up the hash table once in a while [ ] to make sure I don't crash due to excessive memory usage! [+] Your task is to guess to overflow a bucket and DOS me. https://pragmaticcrypto.herokuapp.com/exercise4/
  24. Hash functions def hash(string, seed): return number

  25. Hash functions Hash size Seed? CPB Crc32 32 - 6.9

    Adler32 word - 1.9 MurmurHash3 word yes 0.6 • crcutil.googlecode.com/files/crc-doc.1.0.pdf • http://www.cryptopp.com/benchmarks.html • https://code.google.com/p/smhasher/wiki/MurmurHash3
  26. Real world bug • CVE-2012-5371

  27. Hash functions Hash size Seed? Key? CPB Crc32 32 -

    - 6.9 Adler32 word - - 1.9 MurmurHash3 word yes - 0.6 SipHash 128 - yes ~3.0 • https://131002.net/siphash/siphash.pdf
  28. Practicalities • python -R • Or:

  29. Assignment #5 [+] Your task is twofold: 1) Check if

    the implementation of a hash/dictionary in your favourite programming language is vulnerable to hash-flooding. 2) Implement a single round of siphash in your favoirite programming language. 3) As a bonus point - implement full siphash algorithm! https://pragmaticcrypto.herokuapp.com/exercise5/
  30. Cryptographic hash function

  31. Crypto Hash Fun hash size attack CPB DES 56 2

    39 54.7 MD5 128 2 21 6.8 SHA-1 160 2 61 11.4 SHA-2 256 256 15.8 SHA-2 512 512 17.7 SHA-3 256+ 12.5 • http://www.cryptopp.com/benchmarks.html • http://en.wikipedia.org/wiki/SHA-3
  32. Exhaustive search 8 characters [a-z] ? [a-Z] ? [a-Z0-9] ?

  33. Exhaustive search 8 characters [a-z] 268 = 0.20*1012 [a-Z] 528

    = 53.4*1012 [a-Z0-9] 628 = 218*1012
  34. Workshop #0 $ tar xzf john-1.7.9-jumbo-7.tar.gz $ cd john-1.7.9-jumbo-7/src $

    make linux-x86-sse2 # alternatively: linux-x86-64 # or macosx-x86-sse2 # or macosx-x86-64 $ cd ../run $ ./john --test $ ./john --test | egrep -A2 "raw-md5|raw-sha1"
  35. John The Ripper $ ./john --test Benchmarking: d_0: md5($p) (raw-md5)

    [128/128 SSE2 intrinsics 10x4x3]... DONE Raw: 23805K c/s real, 24046K c/s virtual Benchmarking: d_26: sha1($p) raw-sha1 [128/128 SSE2 4x1]... DONE Raw: 11121K c/s real, 11232K c/s virtual
  36. Exhaustive search: John 8 characters raw md5 [a-z] 268 =

    0.20*1012 ? [a-Z] 528 = 53.4*1012 ? [a-Z0-9] 628 = 218*1012 ?
  37. Exhaustive search: John 8 characters raw md5 [a-z] 268 =

    0.20*1012 2 hours [a-Z] 528 = 53.4*1012 25 days [a-Z0-9] 628 = 218*1012 105 days
  38. Assignment #6 [+] Your task is to break this md5

    checksum: 0b4e7a0e5fe84ad35fb5f95b9ceeac79 [ ] Original string is a 6 character string, [ ] composed from characters from range [a-z0-9]. [+] The original string is: https://pragmaticcrypto.herokuapp.com/exercise6/ Solution: $ echo 0b4e7a0e5fe84ad35fb5f95b9ceeac79 > passwd.raw-md5 $ ./john -i=alnum --format=raw-md5 passwd.raw-md5 $ ./john --format=raw-md5 --show passwd.raw-md5
  39. John’s SLOW! • 5600M c/s MD5 • 2300M c/s SHA1

    • http://www.golubev.com/hashgpu.htm
  40. Exhaustive search: GPU • http://www.golubev.com/hashgpu.htm 8 characters John raw md5

    GPU raw md5 [a-z] 268 = 0.20*1012 2 hours ? [a-Z] 528 = 53.4*1012 25 days ? [a-Z0-9] 628 = 218*1012 105 days ?
  41. Exhaustive search: GPU • http://www.golubev.com/hashgpu.htm 8 characters John raw md5

    GPU raw md5 [a-z] 268 = 0.20*1012 2 hours 37 sec [a-Z] 528 = 53.4*1012 25 days 2 hours [a-Z0-9] 628 = 218*1012 105 days 10 hours
  42. Real world bug

  43. Assignment #7 [*] Your task is to break as many

    passwords hashes [*] from recent leak as possible. [ ] Step 1. Download this SHA1.txt file: Option a) magnet link: Option b) piratebay link: [ ] Step 2. Verify the file: $ shasum SHA1.txt 97018baa4e931e0d02b4ae8ecb1d7d8b6c1b1230 SHA1.txt [ ] Step 3. Crack. ./john --format=Raw-SHA1-LinkedIn ~/SHA1.txt https://pragmaticcrypto.herokuapp.com/exercise7/
  44. Precomputed tables hash key 0x00..01 ca 0x71..AB ma 0xAC..78 ba

  45. Precomputed tables key ca ma ba (hash) • elements: n

    • memory cost: n • lookup: O(log(n))
  46. Precomputed tables 6 8 10 [a-z] [a-Z] [a-Z0-9] 7633383 PiB

  47. Precomputed tables 6 8 10 [a-z] 1.7 GiB 1.6 TiB

    1283 PiB [a-Z] 110 GiB 389 TiB 1314721 PiB [a-Z0-9] 317 GiB 1588 PiB 7633383 PiB
  48. Rainbow tables 0xDE..EF lela fun() 0xFA..DE hash() joey fun()

  49. Rainbow tables last key first key rootroot wikipedia myname abcdefgh

    linux23 passwd • http://kestas.kuliukas.com/RainbowTables/ • https://en.wikipedia.org/wiki/Rainbow_table
  50. • elements: n • size of chain: k • memory

    cost: n/k • lookup: O(k * log(n)) Rainbow tables last key first key ca de ma fa ba gi
  51. Rainbow tables • decrease memory requirements • increase lookup complexity

  52. Real world bug • http://project-rainbowcrack.com/table.htm

  53. Real world bug • https://en.wikipedia.org/wiki/A5/1 • http://opensource.srlabs.de/projects/a51-decrypt

  54. Salting def salted_hash(string, salt): return salt + hash(salt + string))

  55. Assignment #9 [+] I'm a nigerian virus. Please crack these

    hashes for me [+] as I can't afford a computer. BTW. the passwords are [+] composed of excatly 7 characters of digits. [ ] Unsalted ("raw-sha1"): bf683bc25f36e05825647b8e2869bb141a7ef3ed [...] [ ] Salted ("sha1-gen"): $SHA1p$4290117$5d20ebba87900c454a0ab21c81e5ce7185ac59da [...] [ ] Weakly salted ("sha1-gen"): $SHA1p$aaaa$177ab675c3c0aef6a6850b9530da20f8f4d63bdf [...] https://pragmaticcrypto.herokuapp.com/exercise9/
  56. Real world bug • hash(salt + string) != hash(string +

    salt) • Shared prefix speed bump • Length extension attack
  57. Salting • Won’t save you.

  58. None
  59. Dictionary attacks • Passwords aren’t uniformly distributed • password •

    123456 • 12345678 • abc123 • qwerty • mokey • iloveyou • trustno1
  60. Real world bug • http://www.datagenetics.com/blog/september32012/

  61. Real world bug • http://www.datagenetics.com/blog/september32012/

  62. Real world bug • https://www.wpacracker.com/

  63. Assignment #8 [+] Your task is to break this sha512

    password: e860e0aba15c89b31448d0d20625a2c7... [ ] The secret is composed of 4 concatenated lowercase words. [ ] My vocabolary is quite bad, so I used a dictionary [ ] to help me generate a memorizable password: http://www.englishclub.com/vocabulary/common-words-100.htm [+] The original string is: https://pragmaticcrypto.herokuapp.com/exercise8/
  64. Real world bug

  65. Final matters

  66. Lifetime of a hash • http://valerieaurora.org/hash.html

  67. Speed matters hash size attack CPB DES 56 2 39

    54.7 MD5 128 2 21 6.8 SHA-1 160 2 61 11.4 SHA-2 256 256 15.8 SHA-2 512 512 17.7 SHA-3 256+ 12.5 • http://www.cryptopp.com/benchmarks.html • http://en.wikipedia.org/wiki/SHA-3
  68. Conclusion • Is SHA1 better than MD5?

  69. Conclusion • Don’t use hash for passwords: • Storing passwords

    with MD5() or SHA1() is bad (salted or not) • Rephrase: hash functions are not constructed to store your passwords • Hash functions come and go and are optimized for speed • Humans are bad at memorizing passwords • Considering number of sites using MD5 consider not reusing passwords • Beware hash flooding attacks
  70. Finally $ ./john --test Benchmarking: FreeBSD MD5 [128/128 SSE2 intrinsics

    12x]... DONE Raw: 27376 c/s real, 28206 c/s virtual Benchmarking: OpenBSD Blowfish (x32) [32/32 X2]... DONE Raw: 774 c/s real, 789 c/s virtual Benchmarking: Django PBKDF2-HMAC-SHA-256 (x10000) [32/32]... DONE Raw: 42.5 c/s real, 43.0 c/s virtual Benchmarking: WPA-PSK PBKDF2-HMAC-SHA-1 [32/32]... DONE Raw: 340 c/s real, 347 c/s virtual
  71. Real world bug • http://phk.freebsd.dk/sagas/md5crypt.html • http://phk.freebsd.dk/sagas/md5crypt_eol.html