Don't like this style? Click here to change it! blue.css
Overview: In this lesson we're introducing the two "stream"-style block cipher modes. These can be used as pseudo-random number generators. CTR is generally preferred because OFB has a subtle weakness we'll explore.
Notice that both of these modes act like stream-ciphers (the "infinite one-time pad" concept). That is, the block cipher is used to generate a sequence of pseudo-random blocks which are XORed with the message. So the message does not impact the random-blocks.
These modes have some Strengths (S) and some Weaknesses (W) (isn't that always the way):
So this is getting to be old hat by now so let's fly through this. Encrypt the message:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
Using secret key = andy love simone
, IV = Not very random.
with AES as the \(F_k\) and in OFB mode.
The hex digest of the output should be:
4e6f7420766572792072616e646f6d2e91de0aa207cf9f7d0f3cdf245e88f281248b5a2d4cb1b3afefac7bd25c1bc90a177fb88bea185fe13e766cd60a011c20e108f6a8693c756a70da283af3604fb3
Confirm by hand: Compute that by hand, then confirm it by using AES in MODE_OFB (it will only give you the last 64 bytes).
We explore CTR and OFB mode a bit deeper. We also look at a chosen cipher-text attack vulnerability in OFB mode.
If we try to do the same exercise in CTR mode you'll find some variation in what adding 1 means to various implementers. So here is a way to use PyCrypto to get my interpretation (which agrees with some of our books but not all):
from Crypto.Util import Counter
Counter.new(128, initial_value = int(binascii.hexlify('Not very random.'), 16))
Without the IV I get the hex digest:
91de0aa207cf9f7d0f3cdf245e88f28174bd541f6ec64ad071389b2b69597a8fad08b2ef64058797b1e7abae0cd7019eefc3eb0b05c9d6b7333012de03b64701
Prove it: Once everyone can match my outputs and decrypt OFB and CTR then we move on.
Take the encoding we did earlier from OFB mode and change 5 bits anywhere in the ciphertext so that the decryption of your altered text now has a dictionary word in it.
Overview: In this extra lesson I show you a slick method to use one-way functions (like hashes) to create block ciphers.
Now I want to show you one of my favorite cryptography notions: The Feistel Network which is a slick way to take one-way functions and turn them into invertible functions.
Our goal here is to convert our old superHash code into our own block-cipher.
Here is the classic visual (taken from barrywatson.se):
The idea is to split your message into two halves, screw around with one half to make something which looks like noise. Then XOR the other half with the noise. Finally pass the XORed result and the un-screwed half. This gives you everything you need to know to go backwards. (It's even the same exact process.)
Reverse Mentally: Convince yourself that revering one step of the Feistel network is doable by hashing the part that passed in the clear, XORing with the other half, and reversing their spots.
Now we want to have our output have the same bit-length as our input, which was not true for a hash function.
Use the superhash as the one-way function in a Feistel network. Our output is a 256-bit hexadecimal number. So our input should be 512-bits. 8-bits is enough to encode one ASCII character. So our secrets should be 64 characters long.
Build the encryption scheme. Write a function which consumes a length 64 string and a "salt" which now acts like a key. Have your scheme do four rounds of a Feistel network and return a hex string of the 512 bit output. For now you can use 5000 iterations per superhash.