diff options
author | siddharth <s@ricketyspace.net> | 2021-09-19 13:51:43 -0400 |
---|---|---|
committer | siddharth <s@ricketyspace.net> | 2021-09-19 13:51:43 -0400 |
commit | 224ec16b4d9492651f0ae3bb6e4135c022e79705 (patch) | |
tree | a0cddab4695fc63b6871e0375feec874c301a8be /challenge/c27.go | |
parent | 5a7ec9ac19e258b941e7e86b912b87e46d67335f (diff) |
challenge: do challenge 27
Diffstat (limited to 'challenge/c27.go')
-rw-r--r-- | challenge/c27.go | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/challenge/c27.go b/challenge/c27.go new file mode 100644 index 0000000..7b5554e --- /dev/null +++ b/challenge/c27.go @@ -0,0 +1,87 @@ +// Copyright © 2021 rsiddharth <s@ricketyspace.net> +// SPDX-License-Identifier: ISC + +package challenge + +import ( + "fmt" + + "ricketyspace.net/cryptopals/lib" +) + +func C27() { + // Generate random key. + key, err := lib.RandomBytes(16) + if err != nil { + fmt.Printf("Error: %v", err) + return + } + + // Make IV same as `key`. + iv := key + + // Encrypt `plain` with AES-CBC + encrypt := func(plain []byte) []byte { + return lib.AESEncryptCBC(plain, key, iv) + } + + // Same as lib.AESDecryptCBC but ignores padding error and + // checks if plain text has high ASCII values. + // + // Always returns full plain text; even when there is an + // error. + decrypt := func(cipher []byte) ([]byte, error) { + iter := len(cipher) / 16 + + lc := iv + output := make([]byte, 0) + for i := 0; i < iter; i++ { + s := (i * 16) + e := (i * 16) + 16 + c := cipher[s:e] + output = append(output, lib.FixedXORBytes( + lib.AESInvCipher(c, key), lc)...) + + lc = c + } + + // Undo padding + plain, err := lib.Pkcs7PaddingUndo(output) + if err != nil { + // If padding undo fails, just use `output`. + plain = output + } + + // Check if `plain` high ASCII + for _, p := range plain { + if p >= 128 { + return plain, lib.CPError{"Has high ASCII values"} + } + } + + return plain, nil + } + + // Encrypt atleast 3 blocks of plain text. + c := encrypt(lib.StrToBytes( + "As soon as you are born they make you feel small")) + + // Modify cipher. + copy(c[32:48], c[0:16]) // C_3 <- C_1 + copy(c[16:32], lib.FillBytes(0, 16)) // C_2 <- 0 + + // Try decrypting. + p, err := decrypt(c) + if err != nil { + // Has high ASCII values; recover key. + k := lib.FixedXORBytes(p[0:16], p[32:48]) + if lib.BytesEqual(k, key) { + fmt.Printf("Recovered key: %v\n", k) + return + } + } + fmt.Printf("Could not recover key\n") +} + +// Output: +// Recovered key: [62 228 155 158 92 189 217 142 58 118 162 140 165 41 152 237] |