summaryrefslogtreecommitdiffstats
path: root/challenge
diff options
context:
space:
mode:
authorsiddharth <s@ricketyspace.net>2021-10-11 11:29:13 -0400
committersiddharth <s@ricketyspace.net>2021-10-11 11:29:13 -0400
commit51436b8ec20da0f3468db83359b7326747be7ccc (patch)
tree904321a2d6dcdbfb380fd45cb837471b2c5b9b89 /challenge
parent03ce71b250072713270185cd4d035248341c7cdb (diff)
challenge: do challenge 30
Diffstat (limited to 'challenge')
-rw-r--r--challenge/c30.go76
1 files changed, 76 insertions, 0 deletions
diff --git a/challenge/c30.go b/challenge/c30.go
new file mode 100644
index 0000000..0ed6e35
--- /dev/null
+++ b/challenge/c30.go
@@ -0,0 +1,76 @@
+// Copyright © 2021 rsiddharth <s@ricketyspace.net>
+// SPDX-License-Identifier: ISC
+
+package challenge
+
+import (
+ "fmt"
+
+ "ricketyspace.net/cryptopals/lib"
+)
+
+func C30() {
+ // Original message.
+ msg := lib.StrToBytes("comment1=cooking%20MCs;userdata=foo;" +
+ "comment2=%20like%20a%20pound%20of%20bacon")
+
+ // Random secret (unknown to attacker)
+ sec, err := lib.RandomBytes(int(lib.RandomInt(8, 100)))
+ if err != nil {
+ fmt.Printf("Error: unable generate secret\n")
+ }
+
+ // `m` is the original message.
+ // `hvs` is the hash values.
+ // `sl` is the secret key length (guess).
+ genForgedMsgMac := func(m []byte, hvs []uint32, sl int) ([]byte, []byte) {
+ mf := make([]byte, len(m))
+ copy(mf, m)
+ mf = append(mf, lib.Md4Padding(sl+len(m))...)
+ mf = append(mf, lib.StrToBytes(";admin=true")...)
+
+ // Generate MD4 MAC for forged message.
+ md4 := lib.Md4{}
+ md4.Init(hvs)
+ md4.Message(lib.StrToBytes(";admin=true"))
+ // Fudge message length to forged message length.
+ md4.MsgLen = sl + len(mf)
+
+ return mf, md4.Hash()
+ }
+
+ // Returns true if the message is forged.
+ isForged := func(msg, mac []byte) bool {
+ md4 := lib.Md4{}
+ md4.Init([]uint32{})
+ if md4.MacVerify(sec, msg, mac) {
+ return true
+ }
+ return false
+ }
+
+ // Generate MD4 MAC of original message and get the hash
+ // values.
+ md4 := lib.Md4{}
+ md4.Init([]uint32{})
+ msgHVs := lib.BytesToUint32sLittleEndian(md4.Mac(sec, msg)) // Hash values.
+
+ // Try to forge message with different secret prefix lengths.
+ sl := 1
+ for {
+ mf, mac := genForgedMsgMac(msg, msgHVs, sl)
+ if isForged(mf, mac) {
+ fmt.Printf("MD4-MAC successfully forged: %x\n", mac)
+ fmt.Printf("Forged Message: %s\n", mf)
+ fmt.Printf("Secret prefix length: %v\n", sl)
+ break
+ }
+ sl += 1
+ }
+
+}
+
+// Output:
+// MD4-MAC successfully forged: 69384e45320924ab5e63fe5c17d834db
+// Forged Message: comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon8;admin=true
+// Secret prefix length: 90