Slide 1

Slide 1 text

Pragmatic crypto #2: hashing Marek Majkowski

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

Last week

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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/

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Assignments

Slide 10

Slide 10 text

Assignment #0 [+] Your task is to guess my super secure, completely unpredictable password: https://pragmaticcrypto.herokuapp.com/exercise0/ https://github.com/majek/web4crypto

Slide 11

Slide 11 text

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/

Slide 12

Slide 12 text

• 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:

Slide 13

Slide 13 text

• 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/

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

Hash functions

Slide 16

Slide 16 text

Hash function def hash(string): return number

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

Hash table Average Insertion O(1) Deletion O(1) Lookup O(1)

Slide 19

Slide 19 text

Hash table def hash(string): return 3

Slide 20

Slide 20 text

Hash table hash(“Tom”) % 6 = 3 hash(“John”) % 6 = 3 hash(“Sarah”) % 6 = 3 0 1 2 3 4 5 Tom John Sarah X

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

Real world bug • CVE-2011-4815

Slide 23

Slide 23 text

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/

Slide 24

Slide 24 text

Hash functions def hash(string, seed): return number

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

Real world bug • CVE-2012-5371

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

Practicalities • python -R • Or:

Slide 29

Slide 29 text

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/

Slide 30

Slide 30 text

Cryptographic hash function

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

Exhaustive search 8 characters [a-z] ? [a-Z] ? [a-Z0-9] ?

Slide 33

Slide 33 text

Exhaustive search 8 characters [a-z] 268 = 0.20*1012 [a-Z] 528 = 53.4*1012 [a-Z0-9] 628 = 218*1012

Slide 34

Slide 34 text

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"

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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 ?

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

John’s SLOW! • 5600M c/s MD5 • 2300M c/s SHA1 • http://www.golubev.com/hashgpu.htm

Slide 40

Slide 40 text

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 ?

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

Real world bug

Slide 43

Slide 43 text

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/

Slide 44

Slide 44 text

Precomputed tables hash key 0x00..01 ca 0x71..AB ma 0xAC..78 ba

Slide 45

Slide 45 text

Precomputed tables key ca ma ba (hash) • elements: n • memory cost: n • lookup: O(log(n))

Slide 46

Slide 46 text

Precomputed tables 6 8 10 [a-z] [a-Z] [a-Z0-9] 7633383 PiB

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

Rainbow tables 0xDE..EF lela fun() 0xFA..DE hash() joey fun()

Slide 49

Slide 49 text

Rainbow tables last key first key rootroot wikipedia myname abcdefgh linux23 passwd • http://kestas.kuliukas.com/RainbowTables/ • https://en.wikipedia.org/wiki/Rainbow_table

Slide 50

Slide 50 text

• 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

Slide 51

Slide 51 text

Rainbow tables • decrease memory requirements • increase lookup complexity

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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/

Slide 56

Slide 56 text

Real world bug • hash(salt + string) != hash(string + salt) • Shared prefix speed bump • Length extension attack

Slide 57

Slide 57 text

Salting • Won’t save you.

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

Dictionary attacks • Passwords aren’t uniformly distributed • password • 123456 • 12345678 • abc123 • qwerty • mokey • iloveyou • trustno1

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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/

Slide 64

Slide 64 text

Real world bug

Slide 65

Slide 65 text

Final matters

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

Conclusion • Is SHA1 better than MD5?

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

Real world bug • http://phk.freebsd.dk/sagas/md5crypt.html • http://phk.freebsd.dk/sagas/md5crypt_eol.html