From: Zachary Vance Date: Sun, 14 May 2017 09:18:51 +0000 (-0700) Subject: Add all set problems X-Git-Url: https://git.za3k.com/?a=commitdiff_plain;h=4fee92927acf4c489a8085acfe4373f0ef5a17aa;p=cryptopals.git Add all set problems --- diff --git a/problems/set1/1.html b/problems/set-1/1.html similarity index 100% rename from problems/set1/1.html rename to problems/set-1/1.html diff --git a/problems/set1/2.html b/problems/set-1/2.html similarity index 100% rename from problems/set1/2.html rename to problems/set-1/2.html diff --git a/problems/set1/3.html b/problems/set-1/3.html similarity index 100% rename from problems/set1/3.html rename to problems/set-1/3.html diff --git a/problems/set1/4.html b/problems/set-1/4.html similarity index 100% rename from problems/set1/4.html rename to problems/set-1/4.html diff --git a/problems/set1/4.txt b/problems/set-1/4.txt similarity index 100% rename from problems/set1/4.txt rename to problems/set-1/4.txt diff --git a/problems/set1/5.html b/problems/set-1/5.html similarity index 100% rename from problems/set1/5.html rename to problems/set-1/5.html diff --git a/problems/set1/6.html b/problems/set-1/6.html similarity index 100% rename from problems/set1/6.html rename to problems/set-1/6.html diff --git a/problems/set1/6.txt b/problems/set-1/6.txt similarity index 100% rename from problems/set1/6.txt rename to problems/set-1/6.txt diff --git a/problems/set1/7.html b/problems/set-1/7.html similarity index 100% rename from problems/set1/7.html rename to problems/set-1/7.html diff --git a/problems/set1/7.txt b/problems/set-1/7.txt similarity index 100% rename from problems/set1/7.txt rename to problems/set-1/7.txt diff --git a/problems/set1/8.html b/problems/set-1/8.html similarity index 100% rename from problems/set1/8.html rename to problems/set-1/8.html diff --git a/problems/set1/8.txt b/problems/set-1/8.txt similarity index 100% rename from problems/set1/8.txt rename to problems/set-1/8.txt diff --git a/problems/set1/index.html b/problems/set-1/index.html similarity index 85% rename from problems/set1/index.html rename to problems/set-1/index.html index 90a982d..602b21a 100644 --- a/problems/set1/index.html +++ b/problems/set-1/index.html @@ -54,28 +54,28 @@

  1. - Convert hex to base64 + Convert hex to base64
  2. - Fixed XOR + Fixed XOR
  3. - Single-byte XOR cipher + Single-byte XOR cipher
  4. - Detect single-character XOR + Detect single-character XOR
  5. - Implement repeating-key XOR + Implement repeating-key XOR
  6. - Break repeating-key XOR + Break repeating-key XOR
  7. - AES in ECB mode + AES in ECB mode
  8. - Detect AES in ECB mode + Detect AES in ECB mode
@@ -95,4 +95,4 @@ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })();*/ - \ No newline at end of file + diff --git a/problems/set-2/10.html b/problems/set-2/10.html new file mode 100644 index 0000000..9b646fc --- /dev/null +++ b/problems/set-2/10.html @@ -0,0 +1,98 @@ + + + + + Challenge 10 Set 2 - The Cryptopals Crypto Challenges + + + + + + + + +
+ +
+
+ +
+
+
+
+
+

Implement CBC mode

+

+ CBC mode is a block cipher mode that allows us to encrypt irregularly-sized + messages, despite the fact that a block cipher natively only transforms + individual blocks. +

+

+ In CBC mode, each ciphertext block is added to the next plaintext + block before the next call to the cipher core. +

+

+ The first plaintext block, which has no associated previous ciphertext + block, is added to a "fake 0th ciphertext block" called the initialization vector, or IV. +

+

+ Implement CBC mode by hand by taking the ECB function you wrote earlier, + making it encrypt instead of decrypt (verify this by decrypting + whatever you encrypt to test), and using your XOR function from + the previous exercise to combine them. +

+

+ The file here + is intelligible (somewhat) when CBC decrypted against "YELLOW + SUBMARINE" with an IV of all ASCII 0 (\x00\x00\x00 &c) +

+
+
+

Don't cheat.

+
+
+

+ Do not use OpenSSL's CBC code to do CBC mode, even to verify your + results. What's the point of even doing this stuff if you aren't going + to learn from it? +

+
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-2/10.txt b/problems/set-2/10.txt new file mode 100644 index 0000000..f0802a5 --- /dev/null +++ b/problems/set-2/10.txt @@ -0,0 +1,64 @@ +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 diff --git a/problems/set-2/11.html b/problems/set-2/11.html new file mode 100644 index 0000000..7755882 --- /dev/null +++ b/problems/set-2/11.html @@ -0,0 +1,94 @@ + + + + + Challenge 11 Set 2 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

An ECB/CBC detection oracle

+

+ Now that you have ECB and CBC working: +

+

+ Write a function to generate a random AES key; that's just 16 random + bytes. +

+

+ Write a function that encrypts data under an unknown key --- that is, + a function that generates a random key and encrypts under it. +

+

+ The function should look like: +

+
encryption_oracle(your-input)
+=> [MEANINGLESS JIBBER JABBER]
+

+ Under the hood, have the function append 5-10 bytes (count chosen + randomly) before the plaintext and 5-10 bytes after the plaintext. +

+

+ Now, have the function choose to encrypt under ECB 1/2 the time, and + under CBC the other half (just use random IVs each time for CBC). Use + rand(2) to decide which to use. +

+

+ Detect the block cipher mode the function is using each time. You should end + up with a piece of code that, pointed at a block box that might be encrypting + ECB or CBC, tells you which one is happening. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-2/12.html b/problems/set-2/12.html new file mode 100644 index 0000000..346f914 --- /dev/null +++ b/problems/set-2/12.html @@ -0,0 +1,150 @@ + + + + + Challenge 12 Set 2 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Byte-at-a-time ECB decryption (Simple)

+

+ Copy your oracle function to a new function that encrypts buffers + under ECB mode using a consistent but unknown key (for instance, + assign a single random key, once, to a global variable). +

+

+ Now take that same function and have it append to the plaintext, + BEFORE ENCRYPTING, the following string: +

+
Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg
+aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq
+dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg
+YnkK
+
+
+

Spoiler alert.

+
+
+

+ Do not decode this string now. Don't do it. +

+
+
+

+ Base64 decode the string before appending it. Do not base64 decode the + string by hand; make your code do it. The point is that you don't know + its contents. +

+

+ What you have now is a function that produces: +

+
AES-128-ECB(your-string || unknown-string, random-key)
+

+ It turns out: you can decrypt "unknown-string" with repeated calls to the oracle + function! +

+

+ Here's roughly how: +

+ +
    +
  1. + Feed identical bytes of your-string to the function 1 at a time --- + start with 1 byte ("A"), then "AA", then "AAA" and so on. Discover the + block size of the cipher. You know it, but do this step anyway. +
  2. +
  3. + Detect that the function is using ECB. You already know, but do + this step anyways. +
  4. +
  5. + Knowing the block size, craft an input block that is exactly 1 byte + short (for instance, if the block size is 8 bytes, make + "AAAAAAA"). Think about what the oracle function is going to put in + that last byte position. +
  6. +
  7. + Make a dictionary of every possible last byte by feeding different + strings to the oracle; for instance, "AAAAAAAA", "AAAAAAAB", + "AAAAAAAC", remembering the first block of each invocation. +
  8. +
  9. + Match the output of the one-byte-short input to one of the entries + in your dictionary. You've now discovered the first byte of + unknown-string. +
  10. +
  11. + Repeat for the next byte. +
  12. +
+
+
+

Congratulations.

+
+
+

+ This is the first challenge we've given you whose solution will break real crypto. + Lots of people know that when you encrypt something in ECB mode, you can see penguins + through it. Not so many of them can decrypt the contents of those ciphertexts, + and now you can. If our experience is any guideline, this attack will get you code + execution in security tests about once a year. +

+
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-2/13.html b/problems/set-2/13.html new file mode 100644 index 0000000..b2d9983 --- /dev/null +++ b/problems/set-2/13.html @@ -0,0 +1,114 @@ + + + + + Challenge 13 Set 2 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

ECB cut-and-paste

+

+ Write a k=v parsing routine, as if for a structured cookie. The + routine should take: +

+
foo=bar&baz=qux&zap=zazzle
+

+ ... and produce: +

+
{
+  foo: 'bar',
+  baz: 'qux',
+  zap: 'zazzle'
+}
+

+ (you know, the object; I don't care if you convert it to JSON). +

+

+ Now write a function that encodes a user profile in that format, given + an email address. You should have something like: +

+
profile_for("foo@bar.com")
+

+ ... and it should produce: +

+
{
+  email: 'foo@bar.com',
+  uid: 10,
+  role: 'user'
+}
+

+ ... encoded as: +

+
email=foo@bar.com&uid=10&role=user
+

+ Your "profile_for" function should not allow encoding metacharacters + (& and =). Eat them, quote them, whatever you want to do, but don't + let people set their email address to "foo@bar.com&role=admin". +

+

+ Now, two more easy functions. Generate a random AES key, then: +

+
    +
  1. Encrypt the encoded user profile under the key; "provide" that to the "attacker".
  2. +
  3. Decrypt the encoded user profile and parse it.
  4. +
+

+ Using only the user input to profile_for() (as an oracle to generate + "valid" ciphertexts) and the ciphertexts themselves, make a role=admin + profile. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-2/14.html b/problems/set-2/14.html new file mode 100644 index 0000000..18112d4 --- /dev/null +++ b/problems/set-2/14.html @@ -0,0 +1,89 @@ + + + + + Challenge 14 Set 2 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Byte-at-a-time ECB decryption (Harder)

+

+ Take your oracle function + from #12. + Now generate a random count of + random bytes and prepend this string to every plaintext. You are now + doing: +

+
AES-128-ECB(random-prefix || attacker-controlled || target-bytes, random-key)
+

+ Same goal: decrypt the target-bytes. +

+
+
+

Stop and think for a second.

+
+
+

+ What's harder than challenge #12 about doing this? How would you overcome that obstacle? + The hint is: you're using all the tools you already have; no crazy math is required. +

+

+ Think "STIMULUS" and "RESPONSE". +

+
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-2/15.html b/problems/set-2/15.html new file mode 100644 index 0000000..c37a2b1 --- /dev/null +++ b/problems/set-2/15.html @@ -0,0 +1,82 @@ + + + + + Challenge 15 Set 2 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

PKCS#7 padding validation

+

+ Write a function that takes a plaintext, determines if it has valid + PKCS#7 padding, and strips the padding off. +

+

The string:

+
"ICE ICE BABY\x04\x04\x04\x04"
+

... has valid padding, and produces the result "ICE ICE BABY".

+

The string:

+
"ICE ICE BABY\x05\x05\x05\x05"
+

... does not have valid padding, nor does:

+
"ICE ICE BABY\x01\x02\x03\x04"
+

+ If you are writing in a language with exceptions, like Python or Ruby, + make your function throw an exception on bad padding. +

+

+ Crypto nerds know where we're going with this. Bear with us. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-2/16.html b/problems/set-2/16.html new file mode 100644 index 0000000..eee5150 --- /dev/null +++ b/problems/set-2/16.html @@ -0,0 +1,117 @@ + + + + + Challenge 16 Set 2 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

CBC bitflipping attacks

+

+ Generate a random AES key. +

+

+ Combine your padding code and CBC code to write two functions. +

+

+ The first function should take an arbitrary input string, prepend the + string: +

+
"comment1=cooking%20MCs;userdata="
+

.. and append the string:

+
";comment2=%20like%20a%20pound%20of%20bacon"
+

The function should quote out the ";" and "=" characters.

+

+ The function should then pad out the input to the 16-byte AES block + length and encrypt it under the random AES key. +

+

+ The second function should decrypt the string and look for the + characters ";admin=true;" (or, equivalently, decrypt, split the string + on ";", convert each resulting string into 2-tuples, and look for the + "admin" tuple). +

+

Return true or false based on whether the string exists.

+

+ If you've written the first function properly, it should not be + possible to provide user input to it that will generate the string the + second function is looking for. We'll have to break the crypto to do that. +

+

+ Instead, modify the ciphertext (without knowledge of the AES key) to + accomplish this. +

+

+ You're relying on the fact that in CBC mode, a 1-bit error in a + ciphertext block: +

+
    +
  • Completely scrambles the block the error occurs in
  • +
  • Produces the identical 1-bit error(/edit) in the next ciphertext block.
  • +
+
+
+

Stop and think for a second.

+
+
+

+ Before you implement this attack, answer this question: why does CBC + mode have this property? +

+
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-2/9.html b/problems/set-2/9.html new file mode 100644 index 0000000..0a6ee66 --- /dev/null +++ b/problems/set-2/9.html @@ -0,0 +1,83 @@ + + + + + Challenge 9 Set 2 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Implement PKCS#7 padding

+

+ A block cipher transforms a fixed-sized block (usually 8 or 16 bytes) of plaintext + into ciphertext. But we almost never want to transform a single block; we encrypt + irregularly-sized messages. +

+

+ One way we account for irregularly-sized messages is by padding, creating a plaintext + that is an even multiple of the blocksize. The most popular padding scheme is called + PKCS#7. +

+

+ So: pad any block to a specific block length, by appending the number of + bytes of padding to the end of the block. For instance, +

+
"YELLOW SUBMARINE"
+

+ ... padded to 20 bytes would be: +

+
"YELLOW SUBMARINE\x04\x04\x04\x04"
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-2/index.html b/problems/set-2/index.html new file mode 100644 index 0000000..60056db --- /dev/null +++ b/problems/set-2/index.html @@ -0,0 +1,97 @@ + + + + + Set 2 - The Cryptopals Crypto Challenges + + + + + + + + +
+ +
+
+ +
+
+
+
+
+

Crypto Challenge Set 2

+

+ This is the first of several sets on block cipher cryptography. This is bread-and-butter crypto, + the kind you'll see implemented in most web software that does crypto. +

+

+ This set is relatively easy. People that clear set 1 tend to clear set 2 somewhat quickly. +

+

+ Three of the challenges in this set are extremely valuable in breaking real-world crypto; one allows you + to decrypt messages encrypted in the default mode of AES, and the other two allow you to rewrite messages + encrypted in the most popular modes of AES. +

+
    +
  1. + Implement PKCS#7 padding +
  2. +
  3. + Implement CBC mode +
  4. +
  5. + An ECB/CBC detection oracle +
  6. +
  7. + Byte-at-a-time ECB decryption (Simple) +
  8. +
  9. + ECB cut-and-paste +
  10. +
  11. + Byte-at-a-time ECB decryption (Harder) +
  12. +
  13. + PKCS#7 padding validation +
  14. +
  15. + CBC bitflipping attacks +
  16. +
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-3/17.html b/problems/set-3/17.html new file mode 100644 index 0000000..f1e8181 --- /dev/null +++ b/problems/set-3/17.html @@ -0,0 +1,142 @@ + + + + + Challenge 17 Set 3 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

The CBC padding oracle

+

+ This is the best-known attack on modern block-cipher cryptography. +

+

+ Combine your padding code and your CBC code to write two functions. +

+

+ The first function should select at random one of the following 10 + strings: +

+
MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=
+MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=
+MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==
+MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==
+MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl
+MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==
+MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==
+MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=
+MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=
+MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93
+

+ ... generate a random AES key (which it should save for all future + encryptions), pad the string out to the 16-byte AES block size and + CBC-encrypt it under that key, providing the caller the ciphertext and + IV. +

+

+ The second function should consume the ciphertext produced by the + first function, decrypt it, check its padding, and return true or + false depending on whether the padding is valid. +

+
+
+

What you're doing here.

+
+
+

+ This pair of functions approximates AES-CBC encryption as its deployed + serverside in web applications; the second function models the + server's consumption of an encrypted session token, as if it was a + cookie. +

+
+
+

+ It turns out that it's possible to decrypt the ciphertexts provided by + the first function. +

+

+ The decryption here depends on a side-channel leak by the decryption + function. The leak is the error message that the padding is valid or not. +

+

+ You can find 100 web pages on how this attack works, so I won't + re-explain it. What I'll say is this: +

+

+ The fundamental insight behind this attack is that the byte 01h is + valid padding, and occur in 1/256 trials of "randomized" plaintexts + produced by decrypting a tampered ciphertext. +

+

02h in isolation is not valid padding.

+

+ 02h 02h is valid padding, but is much less likely to occur randomly + than 01h. +

+

03h 03h 03h is even less likely.

+

+ So you can assume that if you corrupt a decryption AND it had valid + padding, you know what that padding byte is. +

+

+ It is easy to get tripped up on the fact that CBC plaintexts are + "padded". Padding oracles have nothing to do with the actual padding + on a CBC plaintext. It's an attack that targets a specific bit of code + that handles decryption. You can mount a padding oracle on any CBC + block, whether it's padded or not. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-3/18.html b/problems/set-3/18.html new file mode 100644 index 0000000..8f4ffeb --- /dev/null +++ b/problems/set-3/18.html @@ -0,0 +1,122 @@ + + + + + Challenge 18 Set 3 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Implement CTR, the stream cipher mode

+

The string:

+
L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ==
+

+ ... decrypts to something approximating English in CTR mode, which is an + AES block cipher mode that turns AES into a stream cipher, with the + following parameters: +

+
      key=YELLOW SUBMARINE
+      nonce=0
+      format=64 bit unsigned little endian nonce,
+             64 bit little endian block count (byte count / 16)
+

CTR mode is very simple.

+

+ Instead of encrypting the plaintext, CTR mode encrypts a running + counter, producing a 16 byte block of keystream, which is XOR'd + against the plaintext. +

+

+ For instance, for the first 16 bytes of a message with these + parameters: +

+
keystream = AES("YELLOW SUBMARINE",
+                "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
+

+ ... for the next 16 bytes: +

+
keystream = AES("YELLOW SUBMARINE",
+                "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00")
+

+ ... and then: +

+
keystream = AES("YELLOW SUBMARINE",
+                "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00")
+

+ CTR mode does not require padding; when you run out of plaintext, you + just stop XOR'ing keystream and stop generating keystream. +

+

+ Decryption is identical to encryption. Generate the same keystream, + XOR, and recover the plaintext. +

+

+ Decrypt the string at the top of this function, then use your CTR + function to encrypt and decrypt other things. +

+
+
+

This is the only block cipher mode that matters in good code.

+
+
+

+ Most modern cryptography relies on CTR mode to adapt block ciphers into stream ciphers, + because most of what we want to encrypt is better described as a stream than as a sequence + of blocks. Daniel Bernstein once quipped to Phil Rogaway that good cryptosystems don't need the + "decrypt" transforms. Constructions like CTR are what he was talking about. +

+
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-3/19.html b/problems/set-3/19.html new file mode 100644 index 0000000..5e0d525 --- /dev/null +++ b/problems/set-3/19.html @@ -0,0 +1,144 @@ + + + + + Challenge 19 Set 3 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Break fixed-nonce CTR mode using substitutions

+

+ Take your CTR encrypt/decrypt function and fix its nonce value to + 0. Generate a random AES key. +

+

+ In successive encryptions (not in one big running CTR stream), encrypt + each line of the base64 decodes of the following, + producing multiple independent ciphertexts: +

+
SSBoYXZlIG1ldCB0aGVtIGF0IGNsb3NlIG9mIGRheQ==
+Q29taW5nIHdpdGggdml2aWQgZmFjZXM=
+RnJvbSBjb3VudGVyIG9yIGRlc2sgYW1vbmcgZ3JleQ==
+RWlnaHRlZW50aC1jZW50dXJ5IGhvdXNlcy4=
+SSBoYXZlIHBhc3NlZCB3aXRoIGEgbm9kIG9mIHRoZSBoZWFk
+T3IgcG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==
+T3IgaGF2ZSBsaW5nZXJlZCBhd2hpbGUgYW5kIHNhaWQ=
+UG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==
+QW5kIHRob3VnaHQgYmVmb3JlIEkgaGFkIGRvbmU=
+T2YgYSBtb2NraW5nIHRhbGUgb3IgYSBnaWJl
+VG8gcGxlYXNlIGEgY29tcGFuaW9u
+QXJvdW5kIHRoZSBmaXJlIGF0IHRoZSBjbHViLA==
+QmVpbmcgY2VydGFpbiB0aGF0IHRoZXkgYW5kIEk=
+QnV0IGxpdmVkIHdoZXJlIG1vdGxleSBpcyB3b3JuOg==
+QWxsIGNoYW5nZWQsIGNoYW5nZWQgdXR0ZXJseTo=
+QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=
+VGhhdCB3b21hbidzIGRheXMgd2VyZSBzcGVudA==
+SW4gaWdub3JhbnQgZ29vZCB3aWxsLA==
+SGVyIG5pZ2h0cyBpbiBhcmd1bWVudA==
+VW50aWwgaGVyIHZvaWNlIGdyZXcgc2hyaWxsLg==
+V2hhdCB2b2ljZSBtb3JlIHN3ZWV0IHRoYW4gaGVycw==
+V2hlbiB5b3VuZyBhbmQgYmVhdXRpZnVsLA==
+U2hlIHJvZGUgdG8gaGFycmllcnM/
+VGhpcyBtYW4gaGFkIGtlcHQgYSBzY2hvb2w=
+QW5kIHJvZGUgb3VyIHdpbmdlZCBob3JzZS4=
+VGhpcyBvdGhlciBoaXMgaGVscGVyIGFuZCBmcmllbmQ=
+V2FzIGNvbWluZyBpbnRvIGhpcyBmb3JjZTs=
+SGUgbWlnaHQgaGF2ZSB3b24gZmFtZSBpbiB0aGUgZW5kLA==
+U28gc2Vuc2l0aXZlIGhpcyBuYXR1cmUgc2VlbWVkLA==
+U28gZGFyaW5nIGFuZCBzd2VldCBoaXMgdGhvdWdodC4=
+VGhpcyBvdGhlciBtYW4gSSBoYWQgZHJlYW1lZA==
+QSBkcnVua2VuLCB2YWluLWdsb3Jpb3VzIGxvdXQu
+SGUgaGFkIGRvbmUgbW9zdCBiaXR0ZXIgd3Jvbmc=
+VG8gc29tZSB3aG8gYXJlIG5lYXIgbXkgaGVhcnQs
+WWV0IEkgbnVtYmVyIGhpbSBpbiB0aGUgc29uZzs=
+SGUsIHRvbywgaGFzIHJlc2lnbmVkIGhpcyBwYXJ0
+SW4gdGhlIGNhc3VhbCBjb21lZHk7
+SGUsIHRvbywgaGFzIGJlZW4gY2hhbmdlZCBpbiBoaXMgdHVybiw=
+VHJhbnNmb3JtZWQgdXR0ZXJseTo=
+QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=
+

(This should produce 40 short CTR-encrypted ciphertexts).

+

+ Because the CTR nonce wasn't randomized for each encryption, each + ciphertext has been encrypted against the same keystream. This is very + bad. +

+

+ Understanding that, like most stream ciphers (including RC4, and + obviously any block cipher run in CTR mode), the actual "encryption" + of a byte of data boils down to a single XOR operation, it should be + plain that: +

+
CIPHERTEXT-BYTE XOR PLAINTEXT-BYTE = KEYSTREAM-BYTE
+

And since the keystream is the same for every ciphertext:

+
CIPHERTEXT-BYTE XOR KEYSTREAM-BYTE = PLAINTEXT-BYTE (ie, "you don't
+say!")
+

+ Attack this cryptosystem piecemeal: guess letters, use expected + English language frequence to validate guesses, catch common English + trigrams, and so on. +

+
+
+

Don't overthink it.

+
+
+ Points for automating this, but part of the + reason I'm having you do this is that I think this approach is + suboptimal. +
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-3/20.html b/problems/set-3/20.html new file mode 100644 index 0000000..00db3c3 --- /dev/null +++ b/problems/set-3/20.html @@ -0,0 +1,87 @@ + + + + + Challenge 20 Set 3 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Break fixed-nonce CTR statistically

+

+ In this file + find a similar set of Base64'd plaintext. Do with them exactly + what you did with the first, but solve the problem differently. +

+

+ Instead of making spot guesses at to known plaintext, treat the + collection of ciphertexts the same way you would repeating-key + XOR. +

+

+ Obviously, CTR encryption appears different from repeated-key XOR, + but with a fixed nonce they are effectively the same thing. +

+

+ To exploit this: take your collection of ciphertexts and truncate + them to a common length (the length of the smallest ciphertext will + work). +

+

+ Solve the resulting concatenation of ciphertexts as if for repeating- + key XOR, with a key size of the length of the ciphertext you XOR'd. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-3/20.txt b/problems/set-3/20.txt new file mode 100644 index 0000000..d601f0b --- /dev/null +++ b/problems/set-3/20.txt @@ -0,0 +1,60 @@ +SSdtIHJhdGVkICJSIi4uLnRoaXMgaXMgYSB3YXJuaW5nLCB5YSBiZXR0ZXIgdm9pZCAvIFBvZXRzIGFyZSBwYXJhbm9pZCwgREoncyBELXN0cm95ZWQ= +Q3V6IEkgY2FtZSBiYWNrIHRvIGF0dGFjayBvdGhlcnMgaW4gc3BpdGUtIC8gU3RyaWtlIGxpa2UgbGlnaHRuaW4nLCBJdCdzIHF1aXRlIGZyaWdodGVuaW4nIQ== +QnV0IGRvbid0IGJlIGFmcmFpZCBpbiB0aGUgZGFyaywgaW4gYSBwYXJrIC8gTm90IGEgc2NyZWFtIG9yIGEgY3J5LCBvciBhIGJhcmssIG1vcmUgbGlrZSBhIHNwYXJrOw== +WWEgdHJlbWJsZSBsaWtlIGEgYWxjb2hvbGljLCBtdXNjbGVzIHRpZ2h0ZW4gdXAgLyBXaGF0J3MgdGhhdCwgbGlnaHRlbiB1cCEgWW91IHNlZSBhIHNpZ2h0IGJ1dA== +U3VkZGVubHkgeW91IGZlZWwgbGlrZSB5b3VyIGluIGEgaG9ycm9yIGZsaWNrIC8gWW91IGdyYWIgeW91ciBoZWFydCB0aGVuIHdpc2ggZm9yIHRvbW9ycm93IHF1aWNrIQ== +TXVzaWMncyB0aGUgY2x1ZSwgd2hlbiBJIGNvbWUgeW91ciB3YXJuZWQgLyBBcG9jYWx5cHNlIE5vdywgd2hlbiBJJ20gZG9uZSwgeWEgZ29uZSE= +SGF2ZW4ndCB5b3UgZXZlciBoZWFyZCBvZiBhIE1DLW11cmRlcmVyPyAvIFRoaXMgaXMgdGhlIGRlYXRoIHBlbmFsdHksYW5kIEknbSBzZXJ2aW4nIGE= +RGVhdGggd2lzaCwgc28gY29tZSBvbiwgc3RlcCB0byB0aGlzIC8gSHlzdGVyaWNhbCBpZGVhIGZvciBhIGx5cmljYWwgcHJvZmVzc2lvbmlzdCE= +RnJpZGF5IHRoZSB0aGlydGVlbnRoLCB3YWxraW5nIGRvd24gRWxtIFN0cmVldCAvIFlvdSBjb21lIGluIG15IHJlYWxtIHlhIGdldCBiZWF0IQ== +VGhpcyBpcyBvZmYgbGltaXRzLCBzbyB5b3VyIHZpc2lvbnMgYXJlIGJsdXJyeSAvIEFsbCB5YSBzZWUgaXMgdGhlIG1ldGVycyBhdCBhIHZvbHVtZQ== +VGVycm9yIGluIHRoZSBzdHlsZXMsIG5ldmVyIGVycm9yLWZpbGVzIC8gSW5kZWVkIEknbSBrbm93bi15b3VyIGV4aWxlZCE= +Rm9yIHRob3NlIHRoYXQgb3Bwb3NlIHRvIGJlIGxldmVsIG9yIG5leHQgdG8gdGhpcyAvIEkgYWluJ3QgYSBkZXZpbCBhbmQgdGhpcyBhaW4ndCB0aGUgRXhvcmNpc3Qh +V29yc2UgdGhhbiBhIG5pZ2h0bWFyZSwgeW91IGRvbid0IGhhdmUgdG8gc2xlZXAgYSB3aW5rIC8gVGhlIHBhaW4ncyBhIG1pZ3JhaW5lIGV2ZXJ5IHRpbWUgeWEgdGhpbms= +Rmxhc2hiYWNrcyBpbnRlcmZlcmUsIHlhIHN0YXJ0IHRvIGhlYXI6IC8gVGhlIFItQS1LLUktTSBpbiB5b3VyIGVhcjs= +VGhlbiB0aGUgYmVhdCBpcyBoeXN0ZXJpY2FsIC8gVGhhdCBtYWtlcyBFcmljIGdvIGdldCBhIGF4IGFuZCBjaG9wcyB0aGUgd2Fjaw== +U29vbiB0aGUgbHlyaWNhbCBmb3JtYXQgaXMgc3VwZXJpb3IgLyBGYWNlcyBvZiBkZWF0aCByZW1haW4= +TUMncyBkZWNheWluZywgY3V6IHRoZXkgbmV2ZXIgc3RheWVkIC8gVGhlIHNjZW5lIG9mIGEgY3JpbWUgZXZlcnkgbmlnaHQgYXQgdGhlIHNob3c= +VGhlIGZpZW5kIG9mIGEgcmh5bWUgb24gdGhlIG1pYyB0aGF0IHlvdSBrbm93IC8gSXQncyBvbmx5IG9uZSBjYXBhYmxlLCBicmVha3MtdGhlIHVuYnJlYWthYmxl +TWVsb2RpZXMtdW5tYWthYmxlLCBwYXR0ZXJuLXVuZXNjYXBhYmxlIC8gQSBob3JuIGlmIHdhbnQgdGhlIHN0eWxlIEkgcG9zc2Vz +SSBibGVzcyB0aGUgY2hpbGQsIHRoZSBlYXJ0aCwgdGhlIGdvZHMgYW5kIGJvbWIgdGhlIHJlc3QgLyBGb3IgdGhvc2UgdGhhdCBlbnZ5IGEgTUMgaXQgY2FuIGJl +SGF6YXJkb3VzIHRvIHlvdXIgaGVhbHRoIHNvIGJlIGZyaWVuZGx5IC8gQSBtYXR0ZXIgb2YgbGlmZSBhbmQgZGVhdGgsIGp1c3QgbGlrZSBhIGV0Y2gtYS1za2V0Y2g= +U2hha2UgJ3RpbGwgeW91ciBjbGVhciwgbWFrZSBpdCBkaXNhcHBlYXIsIG1ha2UgdGhlIG5leHQgLyBBZnRlciB0aGUgY2VyZW1vbnksIGxldCB0aGUgcmh5bWUgcmVzdCBpbiBwZWFjZQ== +SWYgbm90LCBteSBzb3VsJ2xsIHJlbGVhc2UhIC8gVGhlIHNjZW5lIGlzIHJlY3JlYXRlZCwgcmVpbmNhcm5hdGVkLCB1cGRhdGVkLCBJJ20gZ2xhZCB5b3UgbWFkZSBpdA== +Q3V6IHlvdXIgYWJvdXQgdG8gc2VlIGEgZGlzYXN0cm91cyBzaWdodCAvIEEgcGVyZm9ybWFuY2UgbmV2ZXIgYWdhaW4gcGVyZm9ybWVkIG9uIGEgbWljOg== +THlyaWNzIG9mIGZ1cnkhIEEgZmVhcmlmaWVkIGZyZWVzdHlsZSEgLyBUaGUgIlIiIGlzIGluIHRoZSBob3VzZS10b28gbXVjaCB0ZW5zaW9uIQ== +TWFrZSBzdXJlIHRoZSBzeXN0ZW0ncyBsb3VkIHdoZW4gSSBtZW50aW9uIC8gUGhyYXNlcyB0aGF0J3MgZmVhcnNvbWU= +WW91IHdhbnQgdG8gaGVhciBzb21lIHNvdW5kcyB0aGF0IG5vdCBvbmx5IHBvdW5kcyBidXQgcGxlYXNlIHlvdXIgZWFyZHJ1bXM7IC8gSSBzaXQgYmFjayBhbmQgb2JzZXJ2ZSB0aGUgd2hvbGUgc2NlbmVyeQ== +VGhlbiBub25jaGFsYW50bHkgdGVsbCB5b3Ugd2hhdCBpdCBtZWFuIHRvIG1lIC8gU3RyaWN0bHkgYnVzaW5lc3MgSSdtIHF1aWNrbHkgaW4gdGhpcyBtb29k +QW5kIEkgZG9uJ3QgY2FyZSBpZiB0aGUgd2hvbGUgY3Jvd2QncyBhIHdpdG5lc3MhIC8gSSdtIGEgdGVhciB5b3UgYXBhcnQgYnV0IEknbSBhIHNwYXJlIHlvdSBhIGhlYXJ0 +UHJvZ3JhbSBpbnRvIHRoZSBzcGVlZCBvZiB0aGUgcmh5bWUsIHByZXBhcmUgdG8gc3RhcnQgLyBSaHl0aG0ncyBvdXQgb2YgdGhlIHJhZGl1cywgaW5zYW5lIGFzIHRoZSBjcmF6aWVzdA== +TXVzaWNhbCBtYWRuZXNzIE1DIGV2ZXIgbWFkZSwgc2VlIGl0J3MgLyBOb3cgYW4gZW1lcmdlbmN5LCBvcGVuLWhlYXJ0IHN1cmdlcnk= +T3BlbiB5b3VyIG1pbmQsIHlvdSB3aWxsIGZpbmQgZXZlcnkgd29yZCdsbCBiZSAvIEZ1cmllciB0aGFuIGV2ZXIsIEkgcmVtYWluIHRoZSBmdXJ0dXJl +QmF0dGxlJ3MgdGVtcHRpbmcuLi53aGF0ZXZlciBzdWl0cyB5YSEgLyBGb3Igd29yZHMgdGhlIHNlbnRlbmNlLCB0aGVyZSdzIG5vIHJlc2VtYmxhbmNl +WW91IHRoaW5rIHlvdSdyZSBydWZmZXIsIHRoZW4gc3VmZmVyIHRoZSBjb25zZXF1ZW5jZXMhIC8gSSdtIG5ldmVyIGR5aW5nLXRlcnJpZnlpbmcgcmVzdWx0cw== +SSB3YWtlIHlhIHdpdGggaHVuZHJlZHMgb2YgdGhvdXNhbmRzIG9mIHZvbHRzIC8gTWljLXRvLW1vdXRoIHJlc3VzY2l0YXRpb24sIHJoeXRobSB3aXRoIHJhZGlhdGlvbg== +Tm92b2NhaW4gZWFzZSB0aGUgcGFpbiBpdCBtaWdodCBzYXZlIGhpbSAvIElmIG5vdCwgRXJpYyBCLidzIHRoZSBqdWRnZSwgdGhlIGNyb3dkJ3MgdGhlIGp1cnk= +WW8gUmFraW0sIHdoYXQncyB1cD8gLyBZbywgSSdtIGRvaW5nIHRoZSBrbm93bGVkZ2UsIEUuLCBtYW4gSSdtIHRyeWluZyB0byBnZXQgcGFpZCBpbiBmdWxs +V2VsbCwgY2hlY2sgdGhpcyBvdXQsIHNpbmNlIE5vcmJ5IFdhbHRlcnMgaXMgb3VyIGFnZW5jeSwgcmlnaHQ/IC8gVHJ1ZQ== +S2FyYSBMZXdpcyBpcyBvdXIgYWdlbnQsIHdvcmQgdXAgLyBaYWtpYSBhbmQgNHRoIGFuZCBCcm9hZHdheSBpcyBvdXIgcmVjb3JkIGNvbXBhbnksIGluZGVlZA== +T2theSwgc28gd2hvIHdlIHJvbGxpbicgd2l0aCB0aGVuPyBXZSByb2xsaW4nIHdpdGggUnVzaCAvIE9mIFJ1c2h0b3duIE1hbmFnZW1lbnQ= +Q2hlY2sgdGhpcyBvdXQsIHNpbmNlIHdlIHRhbGtpbmcgb3ZlciAvIFRoaXMgZGVmIGJlYXQgcmlnaHQgaGVyZSB0aGF0IEkgcHV0IHRvZ2V0aGVy +SSB3YW5uYSBoZWFyIHNvbWUgb2YgdGhlbSBkZWYgcmh5bWVzLCB5b3Uga25vdyB3aGF0IEknbSBzYXlpbic/IC8gQW5kIHRvZ2V0aGVyLCB3ZSBjYW4gZ2V0IHBhaWQgaW4gZnVsbA== +VGhpbmtpbicgb2YgYSBtYXN0ZXIgcGxhbiAvICdDdXogYWluJ3QgbnV0aGluJyBidXQgc3dlYXQgaW5zaWRlIG15IGhhbmQ= +U28gSSBkaWcgaW50byBteSBwb2NrZXQsIGFsbCBteSBtb25leSBpcyBzcGVudCAvIFNvIEkgZGlnIGRlZXBlciBidXQgc3RpbGwgY29taW4nIHVwIHdpdGggbGludA== +U28gSSBzdGFydCBteSBtaXNzaW9uLCBsZWF2ZSBteSByZXNpZGVuY2UgLyBUaGlua2luJyBob3cgY291bGQgSSBnZXQgc29tZSBkZWFkIHByZXNpZGVudHM= +SSBuZWVkIG1vbmV5LCBJIHVzZWQgdG8gYmUgYSBzdGljay11cCBraWQgLyBTbyBJIHRoaW5rIG9mIGFsbCB0aGUgZGV2aW91cyB0aGluZ3MgSSBkaWQ= +SSB1c2VkIHRvIHJvbGwgdXAsIHRoaXMgaXMgYSBob2xkIHVwLCBhaW4ndCBudXRoaW4nIGZ1bm55IC8gU3RvcCBzbWlsaW5nLCBiZSBzdGlsbCwgZG9uJ3QgbnV0aGluJyBtb3ZlIGJ1dCB0aGUgbW9uZXk= +QnV0IG5vdyBJIGxlYXJuZWQgdG8gZWFybiAnY3V6IEknbSByaWdodGVvdXMgLyBJIGZlZWwgZ3JlYXQsIHNvIG1heWJlIEkgbWlnaHQganVzdA== +U2VhcmNoIGZvciBhIG5pbmUgdG8gZml2ZSwgaWYgSSBzdHJpdmUgLyBUaGVuIG1heWJlIEknbGwgc3RheSBhbGl2ZQ== +U28gSSB3YWxrIHVwIHRoZSBzdHJlZXQgd2hpc3RsaW4nIHRoaXMgLyBGZWVsaW4nIG91dCBvZiBwbGFjZSAnY3V6LCBtYW4sIGRvIEkgbWlzcw== +QSBwZW4gYW5kIGEgcGFwZXIsIGEgc3RlcmVvLCBhIHRhcGUgb2YgLyBNZSBhbmQgRXJpYyBCLCBhbmQgYSBuaWNlIGJpZyBwbGF0ZSBvZg== +RmlzaCwgd2hpY2ggaXMgbXkgZmF2b3JpdGUgZGlzaCAvIEJ1dCB3aXRob3V0IG5vIG1vbmV5IGl0J3Mgc3RpbGwgYSB3aXNo +J0N1eiBJIGRvbid0IGxpa2UgdG8gZHJlYW0gYWJvdXQgZ2V0dGluJyBwYWlkIC8gU28gSSBkaWcgaW50byB0aGUgYm9va3Mgb2YgdGhlIHJoeW1lcyB0aGF0IEkgbWFkZQ== +U28gbm93IHRvIHRlc3QgdG8gc2VlIGlmIEkgZ290IHB1bGwgLyBIaXQgdGhlIHN0dWRpbywgJ2N1eiBJJ20gcGFpZCBpbiBmdWxs +UmFraW0sIGNoZWNrIHRoaXMgb3V0LCB5byAvIFlvdSBnbyB0byB5b3VyIGdpcmwgaG91c2UgYW5kIEknbGwgZ28gdG8gbWluZQ== +J0NhdXNlIG15IGdpcmwgaXMgZGVmaW5pdGVseSBtYWQgLyAnQ2F1c2UgaXQgdG9vayB1cyB0b28gbG9uZyB0byBkbyB0aGlzIGFsYnVt +WW8sIEkgaGVhciB3aGF0IHlvdSdyZSBzYXlpbmcgLyBTbyBsZXQncyBqdXN0IHB1bXAgdGhlIG11c2ljIHVw +QW5kIGNvdW50IG91ciBtb25leSAvIFlvLCB3ZWxsIGNoZWNrIHRoaXMgb3V0LCB5byBFbGk= +VHVybiBkb3duIHRoZSBiYXNzIGRvd24gLyBBbmQgbGV0IHRoZSBiZWF0IGp1c3Qga2VlcCBvbiByb2NraW4n +QW5kIHdlIG91dHRhIGhlcmUgLyBZbywgd2hhdCBoYXBwZW5lZCB0byBwZWFjZT8gLyBQZWFjZQ== diff --git a/problems/set-3/21.html b/problems/set-3/21.html new file mode 100644 index 0000000..af76924 --- /dev/null +++ b/problems/set-3/21.html @@ -0,0 +1,73 @@ + + + + + Challenge 21 Set 3 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Implement the MT19937 Mersenne Twister RNG

+

+ You can get the psuedocode for this from Wikipedia. +

+

+ If you're writing + in Python, Ruby, or (gah) PHP, your language is probably already + giving you MT19937 as "rand()"; don't use rand(). Write the RNG + yourself. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-3/22.html b/problems/set-3/22.html new file mode 100644 index 0000000..074b6ef --- /dev/null +++ b/problems/set-3/22.html @@ -0,0 +1,85 @@ + + + + + Challenge 22 Set 3 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Crack an MT19937 seed

+

+ Make sure your MT19937 accepts an integer seed value. Test it (verify + that you're getting the same sequence of outputs given a seed). +

+

+ Write a routine that performs the following operation: +

+
    +
  • Wait a random number of seconds between, I don't know, 40 and 1000.
  • +
  • Seeds the RNG with the current Unix timestamp
  • +
  • Waits a random number of seconds again.
  • +
  • Returns the first 32 bit output of the RNG.
  • +
+

+ You get the idea. Go get coffee while it runs. Or just simulate the + passage of time, although you're missing some of the fun of this + exercise if you do that. +

+

+ From the 32 bit RNG output, discover the seed. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-3/23.html b/problems/set-3/23.html new file mode 100644 index 0000000..906985b --- /dev/null +++ b/problems/set-3/23.html @@ -0,0 +1,108 @@ + + + + + Challenge 23 Set 3 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Clone an MT19937 RNG from its output

+

+ The internal state of MT19937 consists of 624 32 bit integers. +

+

+ For each batch of 624 outputs, MT permutes that internal state. By + permuting state regularly, MT19937 achieves a period of 2**19937, + which is Big. +

+

+ Each time MT19937 is tapped, an element of its internal state is + subjected to a tempering function that diffuses bits through the + result. +

+

+ The tempering function is invertible; you can write an "untemper" + function that takes an MT19937 output and transforms it back into the + corresponding element of the MT19937 state array. +

+

+ To invert the temper transform, apply the inverse of each of the + operations in the temper transform in reverse order. There are two + kinds of operations in the temper transform each applied twice; one is + an XOR against a right-shifted value, and the other is an XOR against + a left-shifted value AND'd with a magic number. So you'll need code to + invert the "right" and the "left" operation. +

+

+ Once you have "untemper" working, create a new MT19937 generator, tap + it for 624 outputs, untemper each of them to recreate the state of the + generator, and splice that state into a new instance of the MT19937 + generator. +

+

+ The new "spliced" generator should predict the values of the original. +

+
+
+

Stop and think for a second.

+
+
+ How would you modify MT19937 to make this attack hard? What would + happen if you subjected each tempered output to a cryptographic hash? +
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-3/24.html b/problems/set-3/24.html new file mode 100644 index 0000000..0b4111b --- /dev/null +++ b/problems/set-3/24.html @@ -0,0 +1,90 @@ + + + + + Challenge 24 Set 3 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Create the MT19937 stream cipher and break it

+

+ You can create a trivial stream cipher out of any PRNG; use it to + generate a sequence of 8 bit outputs and call those outputs a + keystream. XOR each byte of plaintext with each successive byte of + keystream. +

+

+ Write the function that does this for MT19937 using a 16-bit + seed. Verify that you can encrypt and decrypt properly. This code + should look similar to your CTR code. +

+

+ Use your function to encrypt a known plaintext (say, 14 consecutive + 'A' characters) prefixed by a random number of random characters. +

+

+ From the ciphertext, recover the "key" (the 16 bit seed). +

+

+ Use the same idea to generate a random "password reset token" using + MT19937 seeded from the current time. +

+

+ Write a function to check if any given password token is actually + the product of an MT19937 PRNG seeded with the current time. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-3/3.html b/problems/set-3/3.html new file mode 100644 index 0000000..9520518 --- /dev/null +++ b/problems/set-3/3.html @@ -0,0 +1,97 @@ + + + + + Set 3 - The Cryptopals Crypto Challenges + + + + + + + + +
+ +
+
+ +
+
+
+
+
+

Crypto Challenge Set 3

+

+ This is the next set of block cipher cryptography challenges (even the randomness stuff here + plays into block cipher crypto). +

+

+ This set is moderately difficult. It includes a famous attack against CBC mode, and a "cloning" + attack on a popular RNG that can be annoying to get right. +

+

+ We've also reached a point in the crypto challenges where all the challenges, with one possible exception, + are valuable in breaking real-world crypto. +

+
    +
  1. + The CBC padding oracle +
  2. +
  3. + Implement CTR, the stream cipher mode +
  4. +
  5. + Break fixed-nonce CTR mode using substitutions +
  6. +
  7. + Break fixed-nonce CTR statistically +
  8. +
  9. + Implement the MT19937 Mersenne Twister RNG +
  10. +
  11. + Crack an MT19937 seed +
  12. +
  13. + Clone an MT19937 RNG from its output +
  14. +
  15. + Create the MT19937 stream cipher and break it +
  16. +
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-4/25.html b/problems/set-4/25.html new file mode 100644 index 0000000..fbccc21 --- /dev/null +++ b/problems/set-4/25.html @@ -0,0 +1,96 @@ + + + + + Challenge 25 Set 4 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Break "random access read/write" AES CTR

+

+ Back to CTR. Encrypt the recovered plaintext from + this file + (the ECB exercise) under CTR with a random key (for this exercise the + key should be unknown to you, but hold on to it). +

+

+ Now, write the code that allows you to "seek" into the ciphertext, + decrypt, and re-encrypt with different plaintext. Expose this as a + function, like, "edit(ciphertext, key, offset, newtext)". +

+

+ Imagine the "edit" function was exposed to attackers by means of an + API call that didn't reveal the key or the original plaintext; the + attacker has the ciphertext and controls the offset and "new text". +

+

+ Recover the original plaintext. +

+
+
+

Food for thought.

+
+
+

+ A folkloric supposed benefit of CTR mode is the ability to easily + "seek forward" into the ciphertext; to access byte N of the ciphertext, + all you need to be able to do is generate byte N of the keystream. + Imagine if you'd relied on that advice to, say, encrypt a disk. +

+
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-4/25.txt b/problems/set-4/25.txt new file mode 100644 index 0000000..c02ff8a --- /dev/null +++ b/problems/set-4/25.txt @@ -0,0 +1,64 @@ +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 diff --git a/problems/set-4/26.html b/problems/set-4/26.html new file mode 100644 index 0000000..bc0f096 --- /dev/null +++ b/problems/set-4/26.html @@ -0,0 +1,73 @@ + + + + + Challenge 26 Set 4 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

CTR bitflipping

+

+ There are people in the world that believe that CTR resists + bit flipping attacks of the kind to which CBC mode is susceptible. +

+

+ Re-implement + the CBC bitflipping exercise from earlier + to use CTR mode instead of CBC mode. Inject an "admin=true" token. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-4/27.html b/problems/set-4/27.html new file mode 100644 index 0000000..60b1eb4 --- /dev/null +++ b/problems/set-4/27.html @@ -0,0 +1,105 @@ + + + + + Challenge 27 Set 4 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Recover the key from CBC with IV=Key

+

+ Take your code from + the CBC exercise + and modify it so that it + repurposes the key for CBC encryption as the IV. +

+

+ Applications + sometimes use the key as an IV on the auspices that both the sender + and the receiver have to know the key already, and can save some space + by using it as both a key and an IV. +

+

+ Using the key as an IV is insecure; an attacker that can modify + ciphertext in flight can get the receiver to decrypt a value that will + reveal the key. +

+

+ The CBC code from exercise 16 encrypts a URL string. Verify each byte + of the plaintext for ASCII compliance (ie, look for high-ASCII + values). Noncompliant messages should raise an exception or return an + error that includes the decrypted plaintext (this happens all the time + in real systems, for what it's worth). +

+

+ Use your code to encrypt a message that is at least 3 blocks long: +

+
AES-CBC(P_1, P_2, P_3) -> C_1, C_2, C_3
+

+ Modify the message (you are now the attacker): +

+
C_1, C_2, C_3 -> C_1, 0, C_1
+

+ Decrypt the message (you are now the receiver) and raise the + appropriate error if high-ASCII is found. +

+

+ As the attacker, recovering the plaintext from the error, extract the + key: +

+
P'_1 XOR P'_3
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-4/28.html b/problems/set-4/28.html new file mode 100644 index 0000000..439a6c2 --- /dev/null +++ b/problems/set-4/28.html @@ -0,0 +1,88 @@ + + + + + Challenge 28 Set 4 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Implement a SHA-1 keyed MAC

+

+ Find a SHA-1 implementation in the language you code in. +

+
+
+

Don't cheat. It won't work.

+
+
+ Do not use + the SHA-1 implementation your language already provides (for instance, + don't use the "Digest" library in Ruby, or call OpenSSL; in Ruby, + you'd want a pure-Ruby SHA-1). +
+
+

+ Write a function to authenticate a message under a secret key by using + a secret-prefix MAC, which is simply: +

+
SHA1(key || message)
+

+ Verify that you cannot tamper with the message without breaking the + MAC you've produced, and that you can't produce a new MAC without + knowing the secret key. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-4/29.html b/problems/set-4/29.html new file mode 100644 index 0000000..3d9d375 --- /dev/null +++ b/problems/set-4/29.html @@ -0,0 +1,132 @@ + + + + + Challenge 29 Set 4 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Break a SHA-1 keyed MAC using length extension

+

+ Secret-prefix SHA-1 MACs are trivially breakable. +

+

+ The attack on secret-prefix SHA1 relies on the fact that you can take + the ouput of SHA-1 and use it as a new starting point for SHA-1, thus + taking an arbitrary SHA-1 hash and "feeding it more data". +

+

+ Since the key precedes the data in secret-prefix, any additional data + you feed the SHA-1 hash in this fashion will appear to have been + hashed with the secret key. +

+

+ To carry out the attack, you'll need to account for the fact that + SHA-1 is "padded" with the bit-length of the message; your forged + message will need to include that padding. We call this "glue + padding". The final message you actually forge will be: +

+
SHA1(key || original-message || glue-padding || new-message)
+

+ (where the final padding on the whole constructed message is implied) +

+

+ Note that to generate the glue padding, you'll need to know the + original bit length of the message; the message itself is known to the + attacker, but the secret key isn't, so you'll need to guess at it. +

+

+ This sounds more complicated than it is in practice. +

+

+ To implement the attack, first write the function that computes the MD + padding of an arbitrary message and verify that you're generating the + same padding that your SHA-1 implementation is using. This should take + you 5-10 minutes. +

+

+ Now, take the SHA-1 secret-prefix MAC of the message you want to forge + --- this is just a SHA-1 hash --- and break it into 32 bit SHA-1 + registers (SHA-1 calls them "a", "b", "c", &c). +

+

+ Modify your SHA-1 implementation so that callers can pass in new + values for "a", "b", "c" &c (they normally start at magic + numbers). With the registers "fixated", hash the additional data you + want to forge. +

+

+ Using this attack, generate a secret-prefix MAC under a secret key + (choose a random word from /usr/share/dict/words or something) of the + string: +

+
"comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon"
+

+ Forge a variant of this message that ends with ";admin=true". +

+
+
+

This is a very useful attack.

+
+
+

+ For instance: Thai Duong and Juliano Rizzo, who got to this attack before we did, used it to break + the Flickr API. +

+
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-4/30.html b/problems/set-4/30.html new file mode 100644 index 0000000..b946707 --- /dev/null +++ b/problems/set-4/30.html @@ -0,0 +1,82 @@ + + + + + Challenge 30 Set 4 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Break an MD4 keyed MAC using length extension

+

+ Second verse, same as the first, but use MD4 instead of SHA-1. Having + done this attack once against SHA-1, the MD4 variant should take much + less time; mostly just the time you'll spend Googling for an + implementation of MD4. +

+
+
+

You're thinking, why did we bother with this?

+
+
+

+ Blame Stripe. In their second CTF game, the second-to-last challenge involved + breaking an H(k, m) MAC with SHA1. Which meant that SHA1 code was floating all + over the Internet. MD4 code, not so much. +

+
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-4/31.html b/problems/set-4/31.html new file mode 100644 index 0000000..be30c7d --- /dev/null +++ b/problems/set-4/31.html @@ -0,0 +1,111 @@ + + + + + Challenge 31 Set 4 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Implement and break HMAC-SHA1 with an artificial timing leak

+

+ The psuedocode on Wikipedia should be enough. HMAC is very easy. +

+

+ Using the web framework of your choosing (Sinatra, web.py, whatever), + write a tiny application that has a URL that takes a "file" argument + and a "signature" argument, like so: +

+
http://localhost:9000/test?file=foo&signature=46b4ec586117154dacd49d664e5d63fdc88efb51
+

+ Have the server generate an HMAC key, and then verify that the + "signature" on incoming requests is valid for "file", using the "==" + operator to compare the valid MAC for a file with the "signature" + parameter (in other words, verify the HMAC the way any normal + programmer would verify it). +

+

+ Write a function, call it "insecure_compare", that implements the == + operation by doing byte-at-a-time comparisons with early exit (ie, + return false at the first non-matching byte). +

+

+ In the loop for "insecure_compare", add a 50ms sleep (sleep 50ms after + each byte). +

+

+ Use your "insecure_compare" function to verify the HMACs on incoming + requests, and test that the whole contraption works. Return a 500 if + the MAC is invalid, and a 200 if it's OK. +

+

+ Using the timing leak in this application, write a program that + discovers the valid MAC for any file. +

+
+
+

Why artificial delays?

+
+
+ Early-exit string compares are probably the most common source of cryptographic + timing leaks, but they aren't especially easy to exploit. In fact, many timing leaks + (for instance, any in C, C++, Ruby, or Python) probably aren't exploitable over + a wide-area network at all. To play with attacking real-world timing leaks, you + have to start writing low-level timing code. We're keeping things cryptographic + in these challenges. +
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-4/32.html b/problems/set-4/32.html new file mode 100644 index 0000000..e5b0488 --- /dev/null +++ b/problems/set-4/32.html @@ -0,0 +1,71 @@ + + + + + Challenge 32 Set 4 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Break HMAC-SHA1 with a slightly less artificial timing leak

+

+ Reduce the sleep in your "insecure_compare" until your previous + solution breaks. (Try 5ms to start.) +

+

+ Now break it again. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-4/index.html b/problems/set-4/index.html new file mode 100644 index 0000000..ccca38b --- /dev/null +++ b/problems/set-4/index.html @@ -0,0 +1,97 @@ + + + + + Set 4 - The Cryptopals Crypto Challenges + + + + + + + + +
+ +
+
+ +
+
+
+
+
+

Crypto Challenge Set 4

+

+ This is the last set of block cipher cryptography challenges, and also our coverage + of message authentication. +

+

+ This set is much easier than the last set. We introduce some new concepts, but the + attacks themselves involve less code than, say, the CBC padding oracle. +

+

+ Things get significantly trickier in the next two sets. A lot of people drop off after + set 4. +

+
    +
  1. + Break "random access read/write" AES CTR +
  2. +
  3. + CTR bitflipping +
  4. +
  5. + Recover the key from CBC with IV=Key +
  6. +
  7. + Implement a SHA-1 keyed MAC +
  8. +
  9. + Break a SHA-1 keyed MAC using length extension +
  10. +
  11. + Break an MD4 keyed MAC using length extension +
  12. +
  13. + Implement and break HMAC-SHA1 with an artificial timing leak +
  14. +
  15. + Break HMAC-SHA1 with a slightly less artificial timing leak +
  16. +
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-5/33.html b/problems/set-5/33.html new file mode 100644 index 0000000..e98b01a --- /dev/null +++ b/problems/set-5/33.html @@ -0,0 +1,117 @@ + + + + + Challenge 33 Set 5 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Implement Diffie-Hellman

+

+ For one of the most important algorithms in cryptography this exercise + couldn't be a whole lot easier. +

+

+ Set a variable "p" to 37 and "g" to 5. This algorithm is so easy I'm not even + going to explain it. Just do what I do. +

+

+ Generate "a", a random number mod 37. Now generate "A", which is "g" + raised to the "a" power mode 37 --- A = (g**a) % p. +

+

+ Do the same for "b" and "B". +

+

+ "A" and "B" are public keys. Generate a session key with them; set + "s" to "B" raised to the "a" power mod 37 --- s = (B**a) % p. +

+

+ Do the same with A**b, check that you come up with the same "s". +

+

+ To turn "s" into a key, you can just hash it to create 128 bits of + key material (or SHA256 it to create a key for encrypting and a key + for a MAC). +

+

+ Ok, that was fun, now repeat the exercise with bignums like in the real + world. Here are parameters NIST likes: +

+
p:
+ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024
+e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd
+3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec
+6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f
+24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361
+c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552
+bb9ed529077096966d670c354e4abc9804f1746c08ca237327fff
+fffffffffffff
+ 
+g: 2
+

+ This is very easy to do in Python or Ruby or other high-level + languages that auto-promote fixnums to bignums, but it isn't "hard" + anywhere. +

+

+ Note that you'll need to write your own modexp (this is blackboard + math, don't freak out), because you'll blow out your bignum library + raising "a" to the 1024-bit-numberth power. You can find modexp + routines on Rosetta Code for most languages. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-5/34.html b/problems/set-5/34.html new file mode 100644 index 0000000..d986e3a --- /dev/null +++ b/problems/set-5/34.html @@ -0,0 +1,128 @@ + + + + + Challenge 34 Set 5 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Implement a MITM key-fixing attack on Diffie-Hellman with parameter injection

+

+ Use the code you just worked out to build a protocol and an + "echo" bot. You don't actually have to do the network part of this + if you don't want; just simulate that. The protocol is: +

+
+
+ A->B +
+
Send "p", "g", "A"
+
+ B->A +
+
Send "B"
+
+ A->B +
+
Send AES-CBC(SHA1(s)[0:16], iv=random(16), msg) + iv
+
+ B->A +
+
Send AES-CBC(SHA1(s)[0:16], iv=random(16), A's msg) + iv
+
+

+ (In other words, derive an AES key from DH with SHA1, use it in both + directions, and do CBC with random IVs appended or prepended to the + message). +

+

+ Now implement the following MITM attack: +

+
+
A->M
+
Send "p", "g", "A"
+
M->B
+
Send "p", "g", "p"
+
B->M
+
Send "B"
+
M->A
+
Send "p"
+
A->M
+
Send AES-CBC(SHA1(s)[0:16], iv=random(16), msg) + iv
+
M->B
+
Relay that to B
+
B->M
+
Send AES-CBC(SHA1(s)[0:16], iv=random(16), A's msg) + iv
+
M->A
+
Relay that to A
+
+

+ M should be able to decrypt the messages. "A" and "B" in the protocol + --- the public keys, over the wire --- have been swapped out with "p". + Do the DH math on this quickly to see what that does to the + predictability of the key. +

+

+ Decrypt the messages from M's vantage point as they go by. +

+

+ Note that you don't actually have to inject bogus parameters to make + this attack work; you could just generate Ma, MA, Mb, and MB as valid + DH parameters to do a generic MITM attack. But do the parameter + injection attack; it's going to come up again. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-5/35.html b/problems/set-5/35.html new file mode 100644 index 0000000..c9851ad --- /dev/null +++ b/problems/set-5/35.html @@ -0,0 +1,97 @@ + + + + + Challenge 35 Set 5 - The Cryptopals Crypto Challenges + + + + + + + + +
+ +
+
+ +
+
+
+ +
+
+

Implement DH with negotiated groups, and break with malicious "g" parameters

+
+
A->B
+
Send "p", "g"
+
B->A
+
Send ACK
+
A->B
+
Send "A"
+
B->A
+
Send "B"
+
A->B
+
Send AES-CBC(SHA1(s)[0:16], iv=random(16), msg) + iv
+
B->A
+
Send AES-CBC(SHA1(s)[0:16], iv=random(16), A's msg) + iv
+
+

+ Do the MITM attack again, but play with "g". What happens with: +

+
    g = 1
+    g = p
+    g = p - 1
+

+ Write attacks for each. +

+
+
+

When does this ever happen?

+
+
+ Honestly, not that often in real-world systems. If you can mess with "g", chances are + you can mess with something worse. Most systems pre-agree on a static DH group. But + the same construction exists in Elliptic Curve Diffie-Hellman, and this becomes more + relevant there. +
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-5/36.html b/problems/set-5/36.html new file mode 100644 index 0000000..b1a288b --- /dev/null +++ b/problems/set-5/36.html @@ -0,0 +1,127 @@ + + + + + Challenge 36 Set 5 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Implement Secure Remote Password (SRP)

+

+ To understand SRP, look at how you generate an AES key from DH; now, + just observe you can do the "opposite" operation an generate a numeric + parameter from a hash. Then: +

+

+ Replace A and B with C and S (client & server) +

+
C & S
+
Agree on N=[NIST Prime], g=2, k=3, I (email), P (password)
+
S
+
+
    +
  1. Generate salt as random integer
  2. +
  3. Generate string xH=SHA256(salt|password)
  4. +
  5. Convert xH to integer x somehow (put 0x on hexdigest)
  6. +
  7. Generate v=g**x % N
  8. +
  9. Save everything but x, xH
  10. +
+
+
C->S
+
Send I, A=g**a % N (a la Diffie Hellman)
+
S->C
+
Send salt, B=kv + g**b % N
+
S, C
+
Compute string uH = SHA256(A|B), u = integer of uH
+
C
+
+
    +
  1. Generate string xH=SHA256(salt|password)
  2. +
  3. Convert xH to integer x somehow (put 0x on hexdigest)
  4. +
  5. Generate S = (B - k * g**x)**(a + u * x) % N
  6. +
  7. Generate K = SHA256(S)
  8. +
+
+
S
+
+
    +
  1. Generate S = (A * v**u) ** b % N
  2. +
  3. Generate K = SHA256(S)
  4. +
+
+
C->S
+
Send HMAC-SHA256(K, salt)
+
S->C
+
Send "OK" if HMAC-SHA256(K, salt) validates
+

+

+ You're going to want to do this at a REPL of some sort; it may take a + couple tries. +

+

+ It doesn't matter how you go from integer to string or string to + integer (where things are going in or out of SHA256) as long as you do + it consistently. I tested by using the ASCII decimal representation of + integers as input to SHA256, and by converting the hexdigest to an + integer when processing its output. +

+

+ This is basically Diffie Hellman with a tweak of mixing the password + into the public keys. The server also takes an extra step to avoid storing + an easily crackable password-equivalent. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-5/37.html b/problems/set-5/37.html new file mode 100644 index 0000000..def8b0c --- /dev/null +++ b/problems/set-5/37.html @@ -0,0 +1,88 @@ + + + + + Challenge 37 Set 5 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Break SRP with a zero key

+

+ Get your SRP working in an actual client-server setting. "Log in" with + a valid password using the protocol. +

+

+ Now log in without your password by having the client send 0 as its + "A" value. What does this to the "S" value that both sides compute? +

+

+ Now log in without your password by having the client send N, N*2, &c. +

+
+
+

Cryptanalytic MVP award

+
+
+

+ Trevor Perrin and Nate Lawson taught us this attack 7 years ago. It is excellent. + Attacks on DH are tricky to "operationalize". But this attack uses the same concepts, and + results in auth bypass. Almost every implementation of SRP we've ever seen has this flaw; + if you see a new one, go look for this bug. +

+
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-5/38.html b/problems/set-5/38.html new file mode 100644 index 0000000..a1912f0 --- /dev/null +++ b/problems/set-5/38.html @@ -0,0 +1,143 @@ + + + + + Challenge 38 Set 5 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Offline dictionary attack on simplified SRP

+
+
+ S +
+
+
x = SHA256(salt|password)
+    v = g**x % n
+
+
+
+
+ C->S +
+
+
I, A = g**a % n
+
+
+
+
+ S->C +
+
+
salt, B = g**b % n, u = 128 bit random number
+
+
+
+
+ C +
+
+
x = SHA256(salt|password)
+    S = B**(a + ux) % n
+    K = SHA256(S)
+
+
+
+
+ S +
+
+
S = (A * v ** u)**b % n
+    K = SHA256(S)
+
+
+
+
+ C->S +
+
+ Send HMAC-SHA256(K, salt) +
+
+
+
+ S->C +
+
+ Send "OK" if HMAC-SHA256(K, salt) validates +
+
+
+
+
+

+ Note that in this protocol, the server's "B" parameter doesn't depend + on the password (it's just a Diffie Hellman public key). +

+

+ Make sure the protocol works given a valid password. +

+

+ Now, run the protocol as a MITM attacker: pose as the server and use + arbitrary values for b, B, u, and salt. +

+

+ Crack the password from A's HMAC-SHA256(K, salt). +

+
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-5/39.html b/problems/set-5/39.html new file mode 100644 index 0000000..3907ffc --- /dev/null +++ b/problems/set-5/39.html @@ -0,0 +1,123 @@ + + + + + Challenge 39 Set 5 - The Cryptopals Crypto Challenges + + + + + + + + +
+ +
+
+ +
+
+
+ +
+
+

Implement RSA

+

+ There are two annoying things about implementing RSA. Both of them + involve key generation; the actual encryption/decryption in RSA is + trivial. +

+

+ First, you need to generate random primes. You can't just agree on a + prime ahead of time, like you do in DH. You can write this algorithm + yourself, but I just cheat and use OpenSSL's BN library to do the + work. +

+

+ The second is that you need an "invmod" operation (the multiplicative + inverse), which is not an operation that is wired into your + language. The algorithm is just a couple lines, but I always lose an + hour getting it to work. +

+

+ I recommend you not bother with primegen, but do take the time to get + your own EGCD and invmod algorithm working. +

+

+ Now: +

+
    +
  • + Generate 2 random primes. We'll use small numbers to start, so you + can just pick them out of a prime table. Call them "p" and "q". +
  • +
  • + Let n be p * q. Your RSA math is modulo n. +
  • +
  • + Let et be (p-1)*(q-1) (the "totient"). You need this value only for + keygen. +
  • +
  • + Let e be 3. +
  • +
  • + Compute d = invmod(e, et). invmod(17, 3120) is 2753. +
  • +
  • + Your public key is [e, n]. Your private key is [d, n]. +
  • +
  • + To encrypt: c = m**e%n. To decrypt: m = c**d%n +
  • +
  • + Test this out with a number, like "42". +
  • +
  • + Repeat with bignum primes (keep e=3). +
  • +
+

+ Finally, to encrypt a string, do something cheesy, like convert the + string to hex and put "0x" on the front of it to turn it into a + number. The math cares not how stupidly you feed it strings. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-5/40.html b/problems/set-5/40.html new file mode 100644 index 0000000..41e7599 --- /dev/null +++ b/problems/set-5/40.html @@ -0,0 +1,108 @@ + + + + + Challenge 40 Set 5 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Implement an E=3 RSA Broadcast attack

+

+ Assume you're a Javascript programmer. That is, you're using a + naive handrolled RSA to encrypt without padding. +

+

+ Assume you can be coerced into encrypting the same plaintext + three times, under three different public keys. You can; it's + happened. +

+

+ Then an attacker can trivially decrypt your message, by: +

+
    +
  1. Capturing any 3 of the ciphertexts and their corresponding pubkeys
  2. +
  3. + Using the CRT to solve for the number represented by the three + ciphertexts (which are residues mod their respective pubkeys) +
  4. +
  5. Taking the cube root of the resulting number
  6. +
+

+ The CRT says you can take any number and represent it as the + combination of a series of residues mod a series of moduli. In the + three-residue case, you have: +

+
result =
+  (c_0 * m_s_0 * invmod(m_s_0, n_0)) +
+  (c_1 * m_s_1 * invmod(m_s_1, n_1)) +
+  (c_2 * m_s_2 * invmod(m_s_2, n_2)) mod N_012
+

+ where: +

+
 c_0, c_1, c_2 are the three respective residues mod
+ n_0, n_1, n_2
+
+ m_s_n (for n in 0, 1, 2) are the product of the moduli
+ EXCEPT n_n --- ie, m_s_1 is n_0 * n_2
+
+ N_012 is the product of all three moduli
+

+ To decrypt RSA using a simple cube root, leave off the + final modulus operation; just take the raw accumulated result and + cube-root it. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-5/index.html b/problems/set-5/index.html new file mode 100644 index 0000000..d96371b --- /dev/null +++ b/problems/set-5/index.html @@ -0,0 +1,97 @@ + + + + + Set 5 - The Cryptopals Crypto Challenges + + + + + + + + +
+ +
+
+ +
+
+
+
+
+

Crypto Challenge Set 5

+

+ This is the first set of number-theoretic cryptography challenges, and also our coverage + of message authentication. +

+

+ This set is significantly harder than the last set. The concepts are new, the attacks + bear no resemblance to those of the previous sets, and... math. +

+

+ On the other hand, our favorite cryptanalytic attack ever is in this set (you'll see + it soon). We're happy with this set. Don't wimp out here. You're almost done! +

+
    +
  1. + Implement Diffie-Hellman +
  2. +
  3. + Implement a MITM key-fixing attack on Diffie-Hellman with parameter injection +
  4. +
  5. + Implement DH with negotiated groups, and break with malicious "g" parameters +
  6. +
  7. + Implement Secure Remote Password (SRP) +
  8. +
  9. + Break SRP with a zero key +
  10. +
  11. + Offline dictionary attack on simplified SRP +
  12. +
  13. + Implement RSA +
  14. +
  15. + Implement an E=3 RSA Broadcast attack +
  16. +
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-6/41.html b/problems/set-6/41.html new file mode 100644 index 0000000..ba2fdc4 --- /dev/null +++ b/problems/set-6/41.html @@ -0,0 +1,126 @@ + + + + + Challenge 41 Set 6 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Implement unpadded message recovery oracle

+

+ Nate Lawson says we should stop calling it "RSA padding" and start + calling it "RSA armoring". Here's why. +

+

+ Imagine a web application, again with the Javascript encryption, + taking RSA-encrypted messages which (again: Javascript) aren't padded + before encryption at all. +

+

+ You can submit an arbitrary RSA blob and the server will return + plaintext. But you can't submit the same message twice: let's say the + server keeps hashes of previous messages for some liveness interval, + and that the message has an embedded timestamp: +

+
{
+  time: 1356304276,
+  social: '555-55-5555',
+}
+

+ You'd like to capture other people's messages and use the server to + decrypt them. But when you try, the server takes the hash of the + ciphertext and uses it to reject the request. Any bit you flip in the + ciphertext irrevocably scrambles the decryption. +

+

+ This turns out to be trivially breakable: +

+
    +
  • Capture the ciphertext C
  • +
  • Let N and E be the public modulus and exponent respectively
  • +
  • Let S be a random number > 1 mod N. Doesn't matter what.
  • +
  • + Now: +
    C' = ((S**E mod N) C) mod N
    +
  • +
  • + Submit C', which appears totally different from C, to the server, + recovering P', which appears totally different from P +
  • +
  • + Now: +
              P'
    +    P = -----  mod N
    +          S
    +
  • +
+

+ Oops! +

+

+ Implement that attack. +

+
+
+

Careful about division in cyclic groups.

+
+
+ Remember: you don't simply divide mod N; you multiply by the + multiplicative inverse mod N. So you'll need a modinv() function. +
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-6/42.html b/problems/set-6/42.html new file mode 100644 index 0000000..e988ec1 --- /dev/null +++ b/problems/set-6/42.html @@ -0,0 +1,146 @@ + + + + + Challenge 42 Set 6 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Bleichenbacher's e=3 RSA Attack

+
+
+

Crypto-tourism informational placard.

+
+
+

+ This attack broke Firefox's TLS certificate validation several + years ago. You could write a Python script to fake an RSA signature + for any certificate. We find new instances of it every other year + or so. +

+
+
+

+ RSA with an encrypting exponent of 3 is popular, because it makes the + RSA math faster. +

+

+ With e=3 RSA, encryption is just cubing a number mod the public + encryption modulus: +

+
 c = m ** 3 % n
+

+ e=3 is secure as long as we can make assumptions about the message + blocks we're encrypting. The worry with low-exponent RSA is that the + message blocks we process won't be large enough to wrap the modulus + after being cubed. The block 00:02 (imagine sufficient zero-padding) + can be "encrypted" in e=3 RSA; it is simply 00:08. +

+

+ When RSA is used to sign, rather than encrypt, the operations are + reversed; the verifier "decrypts" the message by cubing it. This + produces a "plaintext" which the verifier checks for validity. +

+

+ When you use RSA to sign a message, you supply it a block input that + contains a message digest. The PKCS1.5 standard formats that block as: +

+
00h 01h ffh ffh ... ffh ffh 00h ASN.1 GOOP HASH
+

+ As intended, the ffh bytes in that block expand to fill the whole + block, producing a "right-justified" hash (the last byte of the hash + is the last byte of the message). +

+

+ There was, 7 years ago, a common implementation flaw with RSA + verifiers: they'd verify signatures by "decrypting" them (cubing them + modulo the public exponent) and then "parsing" them by looking for + 00h 01h ... ffh 00h ASN.1 HASH. +

+

+ This is a bug because it implies the verifier isn't checking all the + padding. If you don't check the padding, you leave open the + possibility that instead of hundreds of ffh bytes, you have only a + few, which if you think about it means there could be squizzilions of + possible numbers that could produce a valid-looking signature. +

+

+ How to find such a block? Find a number that when cubed (a) doesn't + wrap the modulus (thus bypassing the key entirely) and (b) produces a + block that starts "00h 01h ffh ... 00h ASN.1 HASH". +

+

+ There are two ways to approach this problem: +

+
    +
  • + You can work from Hal Finney's writeup, available on Google, of how + Bleichenbacher explained the math "so that you can do it by hand + with a pencil". +
  • +
  • + You can implement an integer cube root in your language, format the + message block you want to forge, leaving sufficient trailing zeros + at the end to fill with garbage, then take the cube-root of that + block. +
  • +
+

+ Forge a 1024-bit RSA signature for the string "hi mom". Make sure your + implementation actually accepts the signature! +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-6/43.html b/problems/set-6/43.html new file mode 100644 index 0000000..50177bd --- /dev/null +++ b/problems/set-6/43.html @@ -0,0 +1,150 @@ + + + + + Challenge 43 Set 6 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

DSA key recovery from nonce

+

+ Step 1: Relocate so that you are out of easy travel distance of us. +

+

+ Step 2: Implement DSA, up to signing and verifying, including + parameter generation. +

+

+ Hah-hah you're too far away to come punch us. + +

+

+ Just kidding you can skip the parameter generation part if you + want; if you do, use these params: +

+
 p = 800000000000000089e1855218a0e7dac38136ffafa72eda7
+     859f2171e25e65eac698c1702578b07dc2a1076da241c76c6
+     2d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebe
+     ac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2
+     b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc87
+     1a584471bb1
+ 
+ q = f4f47f05794b256174bba6e9b396a7707e563c5b
+ 
+ g = 5958c9d3898b224b12672c0b98e06c60df923cb8bc999d119
+     458fef538b8fa4046c8db53039db620c094c9fa077ef389b5
+     322a559946a71903f990f1f7e0e025e2d7f7cf494aff1a047
+     0f5b64c36b625a097f1651fe775323556fe00b3608c887892
+     878480e99041be601a62166ca6894bdd41a7054ec89f756ba
+     9fc95302291
+

+ ("But I want smaller params!" Then generate them yourself.) +

+

+ The DSA signing operation generates a random subkey "k". You know this + because you implemented the DSA sign operation. +

+

+ This is the first and easier of two challenges regarding the DSA "k" + subkey. +

+

+ Given a known "k", it's trivial to recover the DSA private key "x": +

+
          (s * k) - H(msg)
+      x = ----------------  mod q
+                  r
+

+ Do this a couple times to prove to yourself that you grok it. Capture + it in a function of some sort. +

+

+ Now then. I used the parameters above. I generated a keypair. My + pubkey is: +

+
  y = 84ad4719d044495496a3201c8ff484feb45b962e7302e56a392aee4
+      abab3e4bdebf2955b4736012f21a08084056b19bcd7fee56048e004
+      e44984e2f411788efdc837a0d2e5abb7b555039fd243ac01f0fb2ed
+      1dec568280ce678e931868d23eb095fde9d3779191b8c0299d6e07b
+      bb283e6633451e535c45513b2d33c99ea17
+

+ I signed +

+
For those that envy a MC it can be hazardous to your health
+So be friendly, a matter of life and death, just like a etch-a-sketch
+

+ (My SHA1 for this string was d2d0714f014a9784047eaeccf956520045c45265; + I don't know what NIST wants you to do, but when I convert that hash + to an integer I get: 0xd2d0714f014a9784047eaeccf956520045c45265). +

+

+ I get: +

+
  r = 548099063082341131477253921760299949438196259240
+  s = 857042759984254168557880549501802188789837994940
+

+ I signed this string with a broken implemention of DSA that generated + "k" values between 0 and 2^16. What's my private key? +

+

+ Its SHA-1 fingerprint (after being converted to hex) is: +

+
0954edd5e0afe5542a4adf012611a91912a3ec16
+

+ Obviously, it also generates the same signature for that string. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-6/44.html b/problems/set-6/44.html new file mode 100644 index 0000000..f685565 --- /dev/null +++ b/problems/set-6/44.html @@ -0,0 +1,123 @@ + + + + + Challenge 44 Set 6 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

DSA nonce recovery from repeated nonce

+
+
+

Cryptanalytic MVP award.

+
+
+

+ This attack (in an elliptic curve group) broke the PS3. It is a great, great attack. +

+
+
+

+ In this file find a collection of DSA-signed messages. + (NB: each msg has a trailing space.) +

+

+ These were signed under the following pubkey: +

+
y = 2d026f4bf30195ede3a088da85e398ef869611d0f68f07
+    13d51c9c1a3a26c95105d915e2d8cdf26d056b86b8a7b8
+    5519b1c23cc3ecdc6062650462e3063bd179c2a6581519
+    f674a61f1d89a1fff27171ebc1b93d4dc57bceb7ae2430
+    f98a6a4d83d8279ee65d71c1203d2c96d65ebbf7cce9d3
+    2971c3de5084cce04a2e147821
+

+ (using the same domain parameters as the previous exercise) +

+

+ It should not be hard to find the messages for which we have + accidentally used a repeated "k". Given a pair of such messages, you + can discover the "k" we used with the following formula: +

+
         (m1 - m2)
+     k = --------- mod q
+         (s1 - s2)
+
+
+

9th Grade Math: Study It!

+
+
+

+ If you want to demystify this, work out that equation from the original DSA equations. +

+
+
+
+
+

Basic cyclic group math operations want to screw you

+
+
+ Remember all this math is mod q; s2 may be larger than s1, for + instance, which isn't a problem if you're doing the subtraction mod + q. If you're like me, you'll definitely lose an hour to forgetting a + paren or a mod q. (And don't forget that modular inverse function!) +
+
+

+ What's my private key? Its SHA-1 (from hex) is: +

+
   ca8f6f7c66fa362d40760d135b763eb8527d3d52
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-6/44.txt b/problems/set-6/44.txt new file mode 100644 index 0000000..3eea46b --- /dev/null +++ b/problems/set-6/44.txt @@ -0,0 +1,44 @@ +msg: Listen for me, you better listen for me now. +s: 1267396447369736888040262262183731677867615804316 +r: 1105520928110492191417703162650245113664610474875 +m: a4db3de27e2db3e5ef085ced2bced91b82e0df19 +msg: Listen for me, you better listen for me now. +s: 29097472083055673620219739525237952924429516683 +r: 51241962016175933742870323080382366896234169532 +m: a4db3de27e2db3e5ef085ced2bced91b82e0df19 +msg: When me rockin' the microphone me rock on steady, +s: 277954141006005142760672187124679727147013405915 +r: 228998983350752111397582948403934722619745721541 +m: 21194f72fe39a80c9c20689b8cf6ce9b0e7e52d4 +msg: Yes a Daddy me Snow me are de article dan. +s: 1013310051748123261520038320957902085950122277350 +r: 1099349585689717635654222811555852075108857446485 +m: 1d7aaaa05d2dee2f7dabdc6fa70b6ddab9c051c5 +msg: But in a in an' a out de dance em +s: 203941148183364719753516612269608665183595279549 +r: 425320991325990345751346113277224109611205133736 +m: 6bc188db6e9e6c7d796f7fdd7fa411776d7a9ff +msg: Aye say where you come from a, +s: 502033987625712840101435170279955665681605114553 +r: 486260321619055468276539425880393574698069264007 +m: 5ff4d4e8be2f8aae8a5bfaabf7408bd7628f43c9 +msg: People em say ya come from Jamaica, +s: 1133410958677785175751131958546453870649059955513 +r: 537050122560927032962561247064393639163940220795 +m: 7d9abd18bbecdaa93650ecc4da1b9fcae911412 +msg: But me born an' raised in the ghetto that I want yas to know, +s: 559339368782867010304266546527989050544914568162 +r: 826843595826780327326695197394862356805575316699 +m: 88b9e184393408b133efef59fcef85576d69e249 +msg: Pure black people mon is all I mon know. +s: 1021643638653719618255840562522049391608552714967 +r: 1105520928110492191417703162650245113664610474875 +m: d22804c4899b522b23eda34d2137cd8cc22b9ce8 +msg: Yeah me shoes a an tear up an' now me toes is a show a +s: 506591325247687166499867321330657300306462367256 +r: 51241962016175933742870323080382366896234169532 +m: bc7ec371d951977cba10381da08fe934dea80314 +msg: Where me a born in are de one Toronto, so +s: 458429062067186207052865988429747640462282138703 +r: 228998983350752111397582948403934722619745721541 +m: d6340bfcda59b6b75b59ca634813d572de800e8f \ No newline at end of file diff --git a/problems/set-6/45.html b/problems/set-6/45.html new file mode 100644 index 0000000..7ac5b40 --- /dev/null +++ b/problems/set-6/45.html @@ -0,0 +1,93 @@ + + + + + Challenge 45 Set 6 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

DSA parameter tampering

+

+ Take your DSA code from the previous exercise. Imagine it as part of + an algorithm in which the client was allowed to propose domain + parameters (the p and q moduli, and the g generator). +

+

+ This would be bad, because attackers could trick victims into accepting + bad parameters. Vaudenay gave two examples of bad generator + parameters: generators that were 0 mod p, and generators that were 1 + mod p. +

+

+ Use the parameters from the previous exercise, but substitute 0 for + "g". Generate a signature. You will notice something bad. Verify the + signature. Now verify any other signature, for any other string. +

+

+ Now, try (p+1) as "g". With this "g", you can generate a magic + signature s, r for any DSA public key that will validate against any + string. For arbitrary z: +

+
  r = ((y**z) % p) % q
+
+        r
+  s =  --- % q
+        z
+

+ Sign "Hello, world". And "Goodbye, world". +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-6/46.html b/problems/set-6/46.html new file mode 100644 index 0000000..0dd7d38 --- /dev/null +++ b/problems/set-6/46.html @@ -0,0 +1,141 @@ + + + + + Challenge 46 Set 6 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

RSA parity oracle

+
+
+

When does this ever happen?

+
+
+ This is a bit of a toy problem, but it's very helpful for + understanding what RSA is doing (and also for why pure + number-theoretic encryption is terrifying). Trust us, you + want to do this before trying the next challenge. Also, + it's fun. +
+
+

+ Generate a 1024 bit RSA key pair. +

+

+ Write an oracle function that uses the private key to answer the + question "is the plaintext of this message even or odd" (is the last + bit of the message 0 or 1). Imagine for instance a server that + accepted RSA-encrypted messages and checked the parity of their + decryption to validate them, and spat out an error if they were of the + wrong parity. +

+

+ Anyways: function returning true or false based on whether the + decrypted plaintext was even or odd, and nothing else. +

+

+ Take the following string and un-Base64 it in your code (without + looking at it!) and encrypt it to the public key, creating a + ciphertext: +

+
VGhhdCdzIHdoeSBJIGZvdW5kIHlvdSBkb24ndCBwbGF5IGFyb3VuZCB3aXRoIHRoZSBGdW5reSBDb2xkIE1lZGluYQ==
+

+ With your oracle function, you can trivially decrypt the message. +

+

+ Here's why: +

+
    +
  • + RSA ciphertexts are just numbers. You can do trivial math on + them. You can for instance multiply a ciphertext by the + RSA-encryption of another number; the corresponding plaintext will + be the product of those two numbers. +
  • +
  • + If you double a ciphertext (multiply it by (2**e)%n), the resulting + plaintext will (obviously) be either even or odd. +
  • +
  • + If the plaintext after doubling is even, doubling the plaintext + didn't wrap the modulus --- the modulus is a prime number. That + means the plaintext is less than half the modulus. +
  • +
+

+ You can repeatedly apply this heuristic, once per bit of the message, + checking your oracle function each time. +

+

+ Your decryption function starts with bounds for the plaintext of [0,n]. +

+

+ Each iteration of the decryption cuts the bounds in half; either the + upper bound is reduced by half, or the lower bound is. +

+

+ After log2(n) iterations, you have the decryption of the message. +

+

+ Print the upper bound of the message as a string at each iteration; + you'll see the message decrypt "hollywood style". +

+

+ Decrypt the string (after encrypting it to a hidden private key) above. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-6/47.html b/problems/set-6/47.html new file mode 100644 index 0000000..a58653e --- /dev/null +++ b/problems/set-6/47.html @@ -0,0 +1,165 @@ + + + + + Challenge 47 Set 6 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Bleichenbacher's PKCS 1.5 Padding Oracle (Simple Case)

+
+
+

Degree of difficulty: moderate

+
+
+ These next two challenges are the hardest in the entire set. +
+
+

+ Let us Google this for you: + + "Chosen ciphertext attacks against protocols based on the RSA encryption standard" + +

+

+ This is Bleichenbacher from CRYPTO '98; I get a bunch of .ps versions + on the first search page. +

+

+ Read the paper. It describes a padding oracle attack on + PKCS#1v1.5. The attack is similar in spirit to the CBC padding oracle + you built earlier; it's an "adaptive chosen ciphertext attack", which + means you start with a valid ciphertext and repeatedly corrupt it, + bouncing the adulterated ciphertexts off the target to learn things + about the original. +

+

+ This is a common flaw even in modern cryptosystems that use RSA. +

+

+ It's also the most fun you can have building a crypto attack. It + involves 9th grade math, but also has you implementing an algorithm + that is complex on par with finding a minimum cost spanning tree. +

+

+ The setup: +

+
    +
  • + Build an oracle function, just like you did in the last exercise, but + have it check for plaintext[0] == 0 and plaintext[1] == 2. +
  • +
  • + Generate a 256 bit keypair (that is, p and q will each be 128 bit + primes), [n, e, d]. +
  • +
  • Plug d and n into your oracle function.
  • +
  • + PKCS1.5-pad a short message, like "kick it, CC", and call it + "m". Encrypt to to get "c". +
  • +
  • + Decrypt "c" using your padding oracle. +
  • +
+

+ For this challenge, we've used an untenably small RSA modulus (you + could factor this keypair instantly). That's because this exercise + targets a specific step in the Bleichenbacher paper --- Step 2c, which + implements a fast, nearly O(log n) search for the plaintext. +

+

+ Things you want to keep in mind as you read the paper: +

+
    +
  • RSA ciphertexts are just numbers.
  • +
  • + RSA is "homomorphic" with respect to multiplication, which means you + can multiply c * RSA(2) to get a c' that will decrypt to plaintext + * 2. This is mindbending but easy to see if you play with it in + code --- try multiplying ciphertexts with the RSA encryptions of + numbers so you know you grok it. +
  • +
  • + What you need to grok for this challenge is that Bleichenbacher uses + multiplication on ciphertexts the way the CBC oracle uses + XORs of random blocks. +
  • +
  • + A PKCS#1v1.5 conformant plaintext, one that starts with 00:02, must be + a number between 02:00:00...00 and 02:FF:FF..FF --- in other + words, 2B and 3B-1, where B is the bit size of the modulus + minus the first 16 bits. When you see 2B and 3B, that's the + idea the paper is playing with. +
  • +
+

+ To decrypt "c", you'll need Step 2a from the paper (the search for the + first "s" that, when encrypted and multiplied with the ciphertext, + produces a conformant plaintext), Step 2c, the fast O(log n) search, + and Step 3. +

+

+ Your Step 3 code is probably not going to need to handle multiple + ranges. +

+

+ We recommend you just use the raw math from paper (check, check, + double check your translation to code) and not spend too much time + trying to grok how the math works. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-6/48.html b/problems/set-6/48.html new file mode 100644 index 0000000..dd5dd1c --- /dev/null +++ b/problems/set-6/48.html @@ -0,0 +1,131 @@ + + + + + Challenge 48 Set 6 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Bleichenbacher's PKCS 1.5 Padding Oracle (Complete Case)

+
+
+

Cryptanalytic MVP award

+
+
+ This is an extraordinarily useful attack. PKCS#1v15 padding, despite being + totally insecure, is the default padding used by RSA implementations. + The OAEP standard that replaces it is not widely implemented. This attack + routinely breaks SSL/TLS. +
+
+

+ This is a continuation of challenge #47; it implements the complete + BB'98 attack. +

+

+ Set yourself up the way you did in #47, but this time generate a 768 + bit modulus. +

+

+ To make the attack work with a realistic RSA keypair, you need to + reproduce step 2b from the paper, and your implementation of Step 3 + needs to handle multiple ranges. +

+

+ The full Bleichenbacher attack works basically like this: +

+
    +
  • + Starting from the smallest 's' that could possibly produce + a plaintext bigger than 2B, iteratively search for an 's' that + produces a conformant plaintext. +
  • +
  • + For our known 's1' and 'n', solve m1=m0s1-rn (again: just a + definition of modular multiplication) for 'r', the number of + times we've wrapped the modulus. +
  • +
  • + 'm0' and 'm1' are unknowns, but we know both are conformant + PKCS#1v1.5 plaintexts, and so are between [2B,3B]. +
  • +
  • + We substitute the known bounds for both, leaving only 'r' + free, and solve for a range of possible 'r' values. This + range should be small! +
  • +
  • + Solve m1=m0s1-rn again but this time for 'm0', plugging in + each value of 'r' we generated in the last step. This gives + us new intervals to work with. Rule out any interval that + is outside 2B,3B. +
  • +
  • + Repeat the process for successively higher values of 's'. + Eventually, this process will get us down to just one + interval, whereupon we're back to exercise #47. +
  • +
+

+ What happens when we get down to one interval is, we stop blindly + incrementing 's'; instead, we start rapidly growing 'r' and backing it + out to 's' values by solving m1=m0s1-rn for 's' instead of 'r' or + 'm0'. So much algebra! Make your teenage son do it for you! *Note: + does not work well in practice* +

+ + +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-6/index.html b/problems/set-6/index.html new file mode 100644 index 0000000..e9192e0 --- /dev/null +++ b/problems/set-6/index.html @@ -0,0 +1,101 @@ + + + + + Set 6 - The Cryptopals Crypto Challenges + + + + + + + + +
+ +
+
+ +
+
+
+
+
+

Crypto Challenge Set 6

+

+ This is the last of our original crypto challenges. +

+

+ This set exclusively covers number-theoretic cryptography, and, in particular, + RSA and DSA. +

+

+ This set is hard. The concepts are again new. The attacks involve some + math --- but nothing you didn't learn in 9th grade --- and a significant amount + of programming. +

+

+ But they're worth it. Two of these attacks in particular are among the most + valuable in real-world cryptography. +

+
    +
  1. + Implement unpadded message recovery oracle +
  2. +
  3. + Bleichenbacher's e=3 RSA Attack +
  4. +
  5. + DSA key recovery from nonce +
  6. +
  7. + DSA nonce recovery from repeated nonce +
  8. +
  9. + DSA parameter tampering +
  10. +
  11. + RSA parity oracle +
  12. +
  13. + Bleichenbacher's PKCS 1.5 Padding Oracle (Simple Case) +
  14. +
  15. + Bleichenbacher's PKCS 1.5 Padding Oracle (Complete Case) +
  16. +
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-7/49.html b/problems/set-7/49.html new file mode 100644 index 0000000..0d41945 --- /dev/null +++ b/problems/set-7/49.html @@ -0,0 +1,188 @@ + + + + + Challenge 49 Set 7 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

CBC-MAC Message Forgery

+

+ Let's talk about CBC-MAC. +

+

+ CBC-MAC is like this: +

+
    +
  1. Take the plaintext P.
  2. +
  3. Encrypt P under CBC with key K, yielding ciphertext C.
  4. +
  5. Chuck all of C but the last block C[n].
  6. +
  7. C[n] is the MAC.
  8. +
+

+ Suppose there's an online banking application, and it carries out user + requests by talking to an API server over the network. Each request + looks like this: +

+
message || IV || MAC
+

+ The message looks like this: +

+
from=#{from_id}&to=#{to_id}&amount=#{amount}
+

+ Now, write an API server and a web frontend for it. (NOTE: No need to + get ambitious and write actual servers and web apps. Totally fine to + go lo-fi on this one.) The client and server should share a secret key + K to sign and verify messages. +

+

+ The API server should accept messages, verify signatures, and carry + out each transaction if the MAC is valid. It's also publicly exposed - + the attacker can submit messages freely assuming he can forge the + right MAC. +

+

+ The web client should allow the attacker to generate valid messages + for accounts he controls. (Feel free to sanitize params if you're + feeling anal-retentive.) Assume the attacker is in a position to + capture and inspect messages from the client to the API server. +

+

+ One thing we haven't discussed is the IV. Assume the client generates + a per-message IV and sends it along with the MAC. That's how CBC + works, right? +

+

+ Wrong. +

+

+ For messages signed under CBC-MAC, an attacker-controlled IV is a + liability. Why? Because it yields full control over the first block of + the message. +

+

+ Use this fact to generate a message transferring 1M spacebucks from a + target victim's account into your account. +

+

+ I'll wait. Just let me know when you're done. +

+

+ ... waiting +

+

+ ... waiting +

+

+ ... waiting +

+

+ All done? Great - I knew you could do it! +

+

+ Now let's tune up that protocol a little bit. +

+

+ As we now know, you're supposed to use a fixed IV with CBC-MAC, so + let's do that. We'll set ours at 0 for simplicity. This means the IV + comes out of the protocol: +

+
message || MAC
+

+ Pretty simple, but we'll also adjust the message. For the purposes of + efficiency, the bank wants to be able to process multiple transactions + in a single request. So the message now looks like this: +

+
from=#{from_id}&tx_list=#{transactions}
+

+ With the transaction list formatted like: +

+
to:amount(;to:amount)*
+

+ There's still a weakness here: the MAC is vulnerable to length + extension attacks. How? +

+

+ Well, the output of CBC-MAC is a valid IV for a new message. +

+

+ "But we don't control the IV anymore!" +

+

+ With sufficient mastery of CBC, we can fake it. +

+

+ Your mission: capture a valid message from your target user. Use + length extension to add a transaction paying the attacker's account 1M + spacebucks. +

+
+
+

Hint!

+
+
+

+ This would be a lot easier if you had full control over the first + block of your message, huh? Maybe you can simulate that. +

+
+
+

+ Food for thought: + How would you modify the protocol to prevent this? +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-7/50.html b/problems/set-7/50.html new file mode 100644 index 0000000..23f4fa6 --- /dev/null +++ b/problems/set-7/50.html @@ -0,0 +1,108 @@ + + + + + Challenge 50 Set 7 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Hashing with CBC-MAC

+

+ Sometimes people try to use CBC-MAC as a hash function. +

+

+ This is a bad idea. Matt Green explains: +

+
+ To make a long story short: cryptographic hash functions are public + functions (i.e., no secret key) that have the property of + collision-resistance (it's hard to find two messages with the same + hash). MACs are keyed functions that (typically) provide message + unforgeability -- a very different property. Moreover, they + guarantee this only when the key is secret. +
+

+ Let's try a simple exercise. +

+

+ Hash functions are often used for code verification. This snippet of + JavaScript (with newline): +

+
alert('MZA who was that?');
+

+ Hashes to + 296b8d7cb78a243dda4d0a61d33bbdd1 + under CBC-MAC with a key of + "YELLOW SUBMARINE" + and a 0 IV. +

+

+ Forge a valid snippet of JavaScript that alerts "Ayo, the Wu is back!" + and hashes to the same value. Ensure that it runs in a browser. +

+
+
+

Extra Credit

+
+
+

+ Write JavaScript code that downloads your file, checks its CBC-MAC, + and inserts it into the DOM iff it matches the expected hash. +

+
+
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-7/51.html b/problems/set-7/51.html new file mode 100644 index 0000000..fea6dec --- /dev/null +++ b/problems/set-7/51.html @@ -0,0 +1,155 @@ + + + + + Challenge 51 Set 7 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Compression Ratio Side-Channel Attacks

+

+ Internet traffic is often compressed to save bandwidth. Until + recently, this included HTTPS headers, and it still includes the + contents of responses. +

+

+ Why does that matter? +

+

+ Well, if you're an attacker with: +

+
    +
  1. Partial plaintext knowledge and
  2. +
  3. Partial plaintext control and
  4. +
  5. Access to a compression oracle
  6. +
+

+ You've got a pretty good chance to recover any additional unknown + plaintext. +

+

+ What's a compression oracle? You give it some input and it tells you + how well the full message compresses, i.e. the length of the resultant + output. +

+

+ This is somewhat similar to the timing attacks we did way back in set + 4 in that we're taking advantage of incidental side channels rather + than attacking the cryptographic mechanisms themselves. +

+

+ Scenario: you are running a MITM attack with an eye towards stealing + secure session cookies. You've injected malicious content allowing you + to spawn arbitrary requests and observe them in flight. (The + particulars aren't terribly important, just roll with it.) +

+

+ So! Write this oracle: +

+
oracle(P) -> length(encrypt(compress(format_request(P))))
+

+ Format the request like this: +

+
POST / HTTP/1.1
+Host: hapless.com
+Cookie: sessionid=TmV2ZXIgcmV2ZWFsIHRoZSBXdS1UYW5nIFNlY3JldCE=
+Content-Length: ((len(P)))
+((P))
+

+ (Pretend you can't see that session id. You're the attacker.) +

+

+ Compress using zlib or whatever. +

+

+ Encryption... is actually kind of irrelevant for our purposes, but be + a sport. Just use some stream cipher. Dealer's choice. Random key/IV + on every call to the oracle. +

+

+ And then just return the length in bytes. +

+

+ Now, the idea here is to leak information using the compression + library. A payload of "sessionid=T" should compress just a little bit + better than, say, "sessionid=S". +

+

+ There is one complicating factor. The DEFLATE algorithm operates in + terms of individual bits, but the final message length will be in + bytes. Even if you do find a better compression, the difference may + not cross a byte boundary. So that's a problem. +

+

+ You may also get some incidental false positives. +

+

+ But don't worry! I have full confidence in you. +

+

+ Use the compression oracle to recover the session id. +

+

+ I'll wait. +

+

+ Got it? Great. +

+

+ Now swap out your stream cipher for CBC and do it again. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-7/52.html b/problems/set-7/52.html new file mode 100644 index 0000000..38c2088 --- /dev/null +++ b/problems/set-7/52.html @@ -0,0 +1,166 @@ + + + + + Challenge 52 Set 7 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Iterated Hash Function Multicollisions

+

+ While we're on the topic of hash functions... +

+

+ The major feature you want in your hash function is + collision-resistance. That is, it should be hard to generate + collisions, and it should be really hard to generate a collision for a + given hash (aka preimage). +

+

+ Iterated hash functions have a problem: the effort to generate lots of + collisions scales sublinearly. +

+

+ What's an iterated hash function? For all intents and purposes, we're + talking about the Merkle-Damgard construction. It looks like this: +

+
function MD(M, H, C):
+  for M[i] in pad(M):
+    H := C(M[i], H)
+  return H
+

+ For message M, initial state H, and compression function C. +

+

+ This should look really familiar, because SHA-1 and MD4 are both in + this category. What's cool is you can use this formula to build a + makeshift hash function out of some spare crypto primitives you have + lying around (e.g. C = AES-128). +

+

+ Back on task: the cost of collisions scales sublinearly. What does + that mean? If it's feasible to find one collision, it's probably + feasible to find a lot. +

+

+ How? For a given state H, find two blocks that collide. Now take the + resulting hash from this collision as your new H and repeat. Recognize + that with each iteration you can actually double your collisions by + subbing in either of the two blocks for that slot. +

+

+ This means that if finding two colliding messages takes 2^(b/2) work + (where b is the bit-size of the hash function), then finding 2^n + colliding messages only takes n*2^(b/2) work. +

+

+ Let's test it. First, build your own MD hash function. We're going to + be generating a LOT of collisions, so don't knock yourself out. In + fact, go out of your way to make it bad. Here's one way: +

+
    +
  1. Take a fast block cipher and use it as C.
  2. +
  3. + Make H pretty small. I won't look down on you if it's only 16 + bits. Pick some initial H. +
  4. +
  5. + H is going to be the input key and the output block from C. That + means you'll need to pad it on the way in and drop bits on the + way out. +
  6. +
+

+ Now write the function f(n) that will generate 2^n collisions in this + hash function. +

+

+ Why does this matter? Well, one reason is that people have tried to + strengthen hash functions by cascading them together. Here's what I + mean: +

+
    +
  1. Take hash functions f and g.
  2. +
  3. Build h such that h(x) = f(x) || g(x).
  4. +
+

+ The idea is that if collisions in f cost 2^(b1/2) and collisions in g + cost 2^(b2/2), collisions in h should come to the princely sum of + 2^((b1+b2)/2). +

+

+ But now we know that's not true! +

+

+ Here's the idea: +

+
    +
  1. Pick the "cheaper" hash function. Suppose it's f.
  2. +
  3. Generate 2^(b2/2) colliding messages in f.
  4. +
  5. There's a good chance your message pool has a collision in g.
  6. +
  7. Find it.
  8. +
+

+ And if it doesn't, keep generating cheap collisions until you find it. +

+

+ Prove this out by building a more expensive (but not too expensive) + hash function to pair with the one you just used. Find a pair of + messages that collide under both functions. Measure the total number + of calls to the collision function. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-7/53.html b/problems/set-7/53.html new file mode 100644 index 0000000..fb1ec9a --- /dev/null +++ b/problems/set-7/53.html @@ -0,0 +1,149 @@ + + + + + Challenge 53 Set 7 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Kelsey and Schneier's Expandable Messages

+

+ One of the basic yardsticks we use to judge a cryptographic hash + function is its resistance to second preimage attacks. That means that + if I give you x and y such that H(x) = y, you should have a tough time + finding x' such that H(x') = H(x) = y. +

+

+ How tough? Brute-force tough. For a 2^b hash function, we want second + preimage attacks to cost 2^b operations. +

+

+ This turns out not to be the case for very long messages. +

+

+ Consider the problem we're trying to solve: we want to find a message + that will collide with H(x) in the very last block. But there are a + ton of intermediate blocks, each with its own intermediate hash + state. +

+

+ What if we could collide into one of those? We could then append all + the following blocks from the original message to produce the original + H(x). Almost. +

+

+ We can't do this exactly because the padding will mess things up. +

+

+ What we need are expandable messages. +

+

+ In the last problem we used multicollisions to produce 2^n colliding + messages for n*2^(b/2) effort. We can use the same principles to + produce a set of messages of length (k, k + 2^k - 1) for a given k. +

+

+ Here's how: +

+
    +
  • + Starting from the hash function's initial state, find a collision + between a single-block message and a message of 2^(k-1)+1 blocks. DO + NOT hash the entire long message each time. Choose 2^(k-1) dummy + blocks, hash those, then focus on the last block. +
  • +
  • + Take the output state from the first step. Use this as your new + initial state and find another collision between a single-block + message and a message of 2^(k-2)+1 blocks. +
  • +
  • + Repeat this process k total times. Your last collision should be + between a single-block message and a message of 2^0+1 = 2 blocks. +
  • +
+

+ Now you can make a message of any length in (k, k + 2^k - 1) blocks by + choosing the appropriate message (short or long) from each pair. +

+

+ Now we're ready to attack a long message M of 2^k blocks. +

+
    +
  1. + Generate an expandable message of length (k, k + 2^k - 1) using + the strategy outlined above. +
  2. +
  3. + Hash M and generate a map of intermediate hash states to the + block indices that they correspond to. +
  4. +
  5. + From your expandable message's final state, find a single-block + "bridge" to intermediate state in your map. Note the index i it + maps to. +
  6. +
  7. + Use your expandable message to generate a prefix of the right + length such that len(prefix || bridge || M[i..]) = len(M). +
  8. +
+

+ The padding in the final block should now be correct, and your forgery + should hash to the same value as M. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-7/54.html b/problems/set-7/54.html new file mode 100644 index 0000000..50db497 --- /dev/null +++ b/problems/set-7/54.html @@ -0,0 +1,152 @@ + + + + + Challenge 54 Set 7 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

Kelsey and Kohno's Nostradamus Attack

+

+ Hash functions are sometimes used as proof of a secret prediction. +

+

+ For example, suppose you wanted to predict the score of every Major + League Baseball game in a season. (2,430 in all.) You might be + concerned that publishing your predictions would affect the + outcomes. +

+

+ So instead you write down all the scores, hash the document, and + publish the hash. Once the season is over, you publish the + document. Everyone can then hash the document to verify your + soothsaying prowess. +

+

+ But what if you can't accurately predict the scores of 2.4k baseball + games? Have no fear - forging a prediction under this scheme reduces + to another second preimage attack. +

+

+ We could apply the long message attack from the previous problem, but + it would look pretty shady. Would you trust someone whose predicted + message turned out to be 2^50 bytes long? +

+

+ It turns out we can run a successful attack with a much shorter + suffix. Check the method: +

+
    +
  1. + Generate a large number of initial hash states. Say, 2^k. +
  2. +
  3. + Pair them up and generate single-block collisions. Now you have + 2^k hash states that collide into 2^(k-1) states. +
  4. +
  5. + Repeat the process. Pair up the 2^(k-1) states and generate + collisions. Now you have 2^(k-2) states. +
  6. +
  7. + Keep doing this until you have one state. This is your + prediction. +
  8. +
  9. + Well, sort of. You need to commit to some length to encode in the + padding. Make sure it's long enough to accommodate your actual + message, this suffix, and a little bit of glue to join them + up. Hash this padding block using the state from step 4 - THIS is + your prediction. +
  10. +
+

+ What did you just build? It's basically a funnel mapping many initial + states into a common final state. What's critical is we now have a big + field of 2^k states we can try to collide into, but the actual suffix + will only be k+1 blocks long. +

+

+ The rest is trivial: +

+
    +
  1. + Wait for the end of the baseball season. (This may take some + time.) +
  2. +
  3. + Write down the game results. Or, you know, anything else. I'm not + too particular. +
  4. +
  5. + Generate enough glue blocks to get your message length right. The + last block should collide into one of the leaves in your + tree. +
  6. +
  7. + Follow the path from the leaf all the way up to the root node and + build your suffix using the message blocks along the way. +
  8. +
+

+ The difficulty here will be around 2^(b-k). By increasing or + decreasing k in the tree generation phase, you can tune the difficulty + of this step. It probably makes sense to do more work up-front, since + people will be waiting on you to supply your message once the event + passes. Happy prognosticating! +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-7/55.html b/problems/set-7/55.html new file mode 100644 index 0000000..f303f17 --- /dev/null +++ b/problems/set-7/55.html @@ -0,0 +1,124 @@ + + + + + Challenge 55 Set 7 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

MD4 Collisions

+

+ MD4 is a 128-bit cryptographic hash function, meaning it should take a + work factor of roughly 2^64 to find collisions. +

+

+ It turns out we can do much better. +

+

+ The paper + + "Cryptanalysis of the Hash Functions MD4 and RIPEMD" + + by Wang + et al details a cryptanalytic attack that lets us find collisions in + 2^8 or less. +

+

+ Given a message block M, Wang outlines a strategy for finding a sister + message block M', differing only in a few bits, that will collide with + it. Just so long as a short set of conditions holds true for M. +

+

+ What sort of conditions? Simple bitwise equalities within the + intermediate hash function state, e.g. a[1][6] = b[0][6]. This should + be read as: "the sixth bit (zero-indexed) of a[1] (i.e. the first + update to 'a') should equal the sixth bit of b[0] (i.e. the initial + value of 'b')". +

+

+ It turns out that a lot of these conditions are trivial to enforce. To + see why, take a look at the first (of three) rounds in the MD4 + compression function. In this round, we iterate over each word in the + message block sequentially and mix it into the state. So we can make + sure all our first-round conditions hold by doing this: +

+
# calculate the new value for a[1] in the normal fashion
+a[1] = (a[0] + f(b[0], c[0], d[0]) + m[0]).lrot(3)
+
+# correct the erroneous bit
+a[1] ^= ((a[1][6] ^ b[0][6]) << 6)
+
+# use algebra to correct the first message block
+m[0] = a[1].rrot(3) - a[0] - f(b[0], c[0], d[0])
+

+ Simply ensuring all the first round conditions puts us well within the + range to generate collisions, but we can do better by correcting some + additional conditions in the second round. This is a bit trickier, as + we need to take care not to stomp on any of the first-round + conditions. +

+

+ Once you've adequately massaged M, you can simply generate M' by + flipping a few bits and test for a collision. A collision is not + guaranteed as we didn't ensure every condition. But hopefully we got + enough that we can find a suitable (M, M') pair without too much + effort. +

+

+ Implement Wang's attack. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-7/56.html b/problems/set-7/56.html new file mode 100644 index 0000000..63951bf --- /dev/null +++ b/problems/set-7/56.html @@ -0,0 +1,150 @@ + + + + + Challenge 56 Set 7 - The Cryptopals Crypto Challenges + + + + + + + + +
+ + +
+
+ +
+
+
+ +
+
+

RC4 Single-Byte Biases

+

+ RC4 is popular stream cipher notable for its usage in protocols like + TLS, WPA, RDP, &c. +

+

+ It's also susceptible to significant single-byte biases, especially + early in the keystream. What does this mean? +

+

+ Simply: for a given position in the keystream, certain bytes are more + (or less) likely to pop up than others. Given enough encryptions of a + given plaintext, an attacker can use these biases to recover the + entire plaintext. +

+

+ Now, search online for + + "On the Security of RC4 in TLS and WPA". + + This + site is your one-stop shop for RC4 information. +

+

+ Click through to "RC4 biases" on the right. +

+

+ These are graphs of each single-byte bias (one per page). Notice in + particular the monster spikes on z16, z32, z48, etc. (Note: these are + one-indexed, so z16 = keystream[15].) +

+

+ How useful are these biases? +

+

+ Click through to the research paper and scroll down to the simulation + results. (Incidentally, the whole paper is a good read if you have + some spare time.) We start out with clear spikes at 2^26 iterations, + but our chances for recovering each of the first 256 bytes approaches + 1 as we get up towards 2^32. +

+

+ There are two ways to take advantage of these biases. The first method + is really simple: +

+
    +
  1. Gain exhaustive knowledge of the keystream biases.
  2. +
  3. Encrypt the unknown plaintext 2^30+ times under different keys.
  4. +
  5. Compare the ciphertext biases against the keystream biases.
  6. +
+

+ Doing this requires deep knowledge of the biases for each byte of the + keystream. But it turns out we can do pretty well with just a few + useful biases - if we have some control over the plaintext. +

+

+ How? By using knowledge of a single bias as a peephole into the + plaintext. +

+

+ Decode this secret: +

+
QkUgU1VSRSBUTyBEUklOSyBZT1VSIE9WQUxUSU5F
+

+ And call it a cookie. No peeking! +

+

+ Now use it to build this encryption oracle: +

+
RC4(your-request || cookie, random-key)
+

+ Use a fresh 128-bit key on every invocation. +

+

+ Picture this scenario: you want to steal a user's secure cookie. You + can spawn arbitrary requests (from a malicious plugin or somesuch) and + monitor network traffic. (Ok, this is unrealistic - the cookie + wouldn't be right at the beginning of the request like that - this is + just an example!) +

+

+ You can control the position of the cookie by requesting "/", "/A", + "/AA", and so on. +

+

+ Build bias maps for a couple chosen indices (z16 and z32 are good) and + decrypt the cookie. +

+
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-7/index.html b/problems/set-7/index.html new file mode 100644 index 0000000..b7ab762 --- /dev/null +++ b/problems/set-7/index.html @@ -0,0 +1,98 @@ + + + + + Set 7 - The Cryptopals Crypto Challenges + + + + + + + + +
+ +
+
+ +
+
+
+
+
+

Crypto Challenge Set 7

+

+ This is the first of two sets we generated after the original 6. +

+

+ Unlike the last few sets, this set is a hodge-podge. It also includes + some of the few challenges we have that probably aren't useful against + real targets (they were fun enough to include anyways). On the other + hand, we also include a challenge that models the CRIME attack on TLS. +

+

+ This set is hard. There's a significant amount of programming, + and Wang's attack in particular is as difficult as anything we've done. +

+
    +
  1. + CBC-MAC Message Forgery +
  2. +
  3. + Hashing with CBC-MAC +
  4. +
  5. + Compression Ratio Side-Channel Attacks +
  6. +
  7. + Iterated Hash Function Multicollisions +
  8. +
  9. + Kelsey and Schneier's Expandable Messages +
  10. +
  11. + Kelsey and Kohno's Nostradamus Attack +
  12. +
  13. + MD4 Collisions +
  14. +
  15. + RC4 Single-Byte Biases +
  16. +
+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file diff --git a/problems/set-8/index.html b/problems/set-8/index.html new file mode 100644 index 0000000..d521a37 --- /dev/null +++ b/problems/set-8/index.html @@ -0,0 +1,84 @@ + + + + + Set 8 - The Cryptopals Crypto Challenges + + + + + + + + +
+ +
+
+ +
+
+
+
+
+

Crypto Challenge Set 8

+

+ This is the second of two sets we generated after the original 6. +

+

+ This set focuses on abstract algebra, including DH, GCM, and (most + importantly) elliptic curve cryptography. + + Fair warning - it's really tough! There's a ton of content here, and + it's more demanding than anything we've released so far. By the time + you're done, you will have written an ad hoc, informally-specified, + bug-ridden, slow implementation of one percent of SageMath. +

+
    +
  1. Diffie-Hellman Revisited: Small Subgroup Confinement
  2. +
  3. Pollard's Method for Catching Kangaroos
  4. +
  5. Elliptic Curve Diffie-Hellman and Invalid-Curve Attacks
  6. +
  7. Single-Coordinate Ladders and Insecure Twists
  8. +
  9. Duplicate-Signature Key Selection in ECDSA (and RSA)
  10. +
  11. Key-Recovery Attacks on ECDSA with Biased Nonces
  12. +
  13. Key-Recovery Attacks on GCM with Repeated Nonces
  14. +
  15. Key-Recovery Attacks on GCM with a Truncated MAC
  16. +
+

+ But wait, where are the actual challenges?! You'll need to mail in for them, just like in the original cryptopals. Send a mail to set#.cryptopals@gmail.com and make the subject "Crazy Flamboyant for the Rap Enjoyment". BUT replace the # with the number of the set you want. Which would be 8. So replace it with 8. +

+ +
+
+
+
Cryptography Services | NCC Group
+ + + \ No newline at end of file