Skip to content

Instantly share code, notes, and snippets.

@michaelficarra
Created October 17, 2013 21:38
Show Gist options
  • Select an option

  • Save michaelficarra/7032644 to your computer and use it in GitHub Desktop.

Select an option

Save michaelficarra/7032644 to your computer and use it in GitHub Desktop.
matasano crypto class notes/assignments
import Data.Char
import Data.Word
import Data.Bits
import Data.List
import Data.Maybe
import qualified Data.ByteString as B
import Codec.Crypto.AES
repeatedKeyXor = do
bs <- B.readFile "./test.file"
let key = [80, 25, 64, 3]
let encrypted = B.pack $ zipWith xor (cycle key) $ B.unpack bs
putStrLn $ show $ encrypted
aesBlockSize = 16 -- bytes
pad size char bs = B.append bs $ strToBs $ replicate (mod (size - mod (B.length bs) size) size) char
strToBs str = B.pack $ map ((.&. 0xFF) . fromIntegral . ord) str
ecbCrypt key str =
let bs = strToBs str in
let key' = pad aesBlockSize '\0' $ strToBs key in
let iv = B.pack $ replicate aesBlockSize 0 in
crypt' ECB key' iv Encrypt $ pad aesBlockSize '\0' bs
cbcCrypt key str =
let bs = strToBs str in
let key' = pad aesBlockSize '\0' $ strToBs key in
let iv = B.pack $ replicate aesBlockSize 0 in -- XXX: unsafe
crypt' CBC key' iv Encrypt $ pad aesBlockSize '\0' bs
ctrCrypt key str =
let bs = strToBs str in
let key' = pad aesBlockSize '\0' $ strToBs key in
let iv = B.pack $ replicate aesBlockSize 0 in -- XXX: unsafe
crypt' CTR key' iv Encrypt bs
suffix = ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
knownNumberOfBlocks = (length suffix `div` aesBlockSize) + 1
offsets = take (knownNumberOfBlocks * aesBlockSize) $ (cycle [(aesBlockSize - 1), (aesBlockSize - 2) .. 0])
server plaintext = ecbCrypt "their secret key" (plaintext ++ suffix)
findTheCharacter followingCharacters (offset, targetBlock) =
let knownCiphertext = B.take (aesBlockSize * targetBlock) $ server $ replicate offset 'a' in
let possibilities = [(ch, B.take (aesBlockSize * targetBlock) $ server $ replicate offset 'a' ++ followingCharacters ++ [ch]) | ch <- ['\0'..'\255']] in
let matchingPossibility = find (\pair -> (snd pair) == knownCiphertext) possibilities in
let nextChar = fst $ fromMaybe ('\0', B.empty) matchingPossibility in
followingCharacters ++ [nextChar]
assignment = foldl findTheCharacter "" $ zip offsets (concat $ [replicate aesBlockSize x | x <- [1..]])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment