· 7 years ago · Mar 26, 2018, 04:26 AM
1package main
2
3import (
4 hmaclib "crypto/hmac"
5 "crypto/md5"
6 "encoding/hex"
7 "fmt"
8 "hash"
9)
10
11func ComputeHmacCorrect(message string, secret string) string {
12 h := hmaclib.New(md5.New, []byte(secret))
13 h.Write([]byte(message))
14 sum := h.Sum(nil)
15 return hex.EncodeToString(sum[:])
16}
17
18func ComputeHmacCustom(message string, key_str string) string {
19 key := []byte(key_str)
20 h := md5.New
21
22 hm := new(hmac)
23 // New
24 {
25 hm.outer = h()
26 hm.inner = h()
27 hm.size = hm.inner.Size()
28 hm.blocksize = hm.inner.BlockSize()
29 hm.ipad = make([]byte, hm.blocksize)
30 hm.opad = make([]byte, hm.blocksize)
31 if len(key) > hm.blocksize {
32 // If key is too big, hash it.
33 hm.outer.Write(key)
34 key = hm.outer.Sum(nil)
35 }
36 copy(hm.ipad, key)
37 copy(hm.opad, key)
38 for i := range hm.ipad {
39 hm.ipad[i] ^= 0x36
40 }
41 for i := range hm.opad {
42 hm.opad[i] ^= 0x5c
43 }
44 hm.inner.Write(hm.ipad)
45 }
46
47 // DEBUG: Inner MD5
48 {
49 hm.Write([]byte(message))
50 return hex.EncodeToString(hm.inner.Sum(nil))
51 }
52
53 // Write
54 {
55 hm.Write([]byte(message))
56 }
57
58 // Sum(in)
59 var sum []byte
60 {
61 var in []byte = nil
62 h := hm
63 origLen := len(in)
64 in = h.inner.Sum(in)
65 h.outer.Reset()
66 h.outer.Write(h.opad)
67 h.outer.Write(in[origLen:])
68 //panic(fmt.Sprintf("%v", in[origLen:]))
69 sum = h.outer.Sum(in[:origLen])
70 }
71 return hex.EncodeToString(sum[:])
72}
73
74func main() {
75 secretKey := "secret_key"
76 //secretKey := "ff772e31410ae7f31b93c2109f496006ff772e31410ae7f31b93c2109f496006"
77 fmt.Printf("--------------------------------------------------------\n")
78 fmt.Printf("Normal implementation \n")
79 fmt.Printf("--------------------------------------------------------\n")
80 fmt.Printf("String A - %s\n", ComputeHmacCorrect(string([]byte{'A'}), secretKey))
81 fmt.Printf("String A with zero byte terminator - %s\n", ComputeHmacCorrect(string([]byte{'A', 0}), secretKey))
82 fmt.Printf("Empty string - %s\n", ComputeHmacCorrect("", secretKey))
83 fmt.Printf("Empty string with zero byte - %s\n", ComputeHmacCorrect(string([]byte{0}), secretKey))
84 fmt.Printf("--------------------------------------------------------\n")
85 fmt.Printf("Custom implementation \n")
86 fmt.Printf("--------------------------------------------------------\n")
87 fmt.Printf("String A - %s\n", ComputeHmacCustom(string([]byte{'A'}), secretKey))
88 fmt.Printf("String A with zero byte terminator - %s\n", ComputeHmacCustom(string([]byte{'A', 0}), secretKey))
89 fmt.Printf("Empty string - %s\n", ComputeHmacCustom("", secretKey))
90 fmt.Printf("Empty string with zero byte - %s\n", ComputeHmacCustom(string([]byte{0}), secretKey))
91 panic(".")
92}
93
94// ---
95
96type hmac struct {
97 size int
98 blocksize int
99 opad, ipad []byte
100 outer, inner hash.Hash
101}
102
103func (h *hmac) Sum(in []byte) []byte {
104 origLen := len(in)
105 in = h.inner.Sum(in)
106 //in = []byte(hex.EncodeToString(h.inner.Sum(in)))
107 //fmt.Printf("Inner MD5: %s\n", hex.EncodeToString(in))
108 h.outer.Reset()
109 h.outer.Write(h.opad)
110 h.outer.Write(in[origLen:])
111 return h.outer.Sum(in[:origLen])
112}
113
114func (h *hmac) Write(p []byte) (n int, err error) {
115 return h.inner.Write(p)
116}
117
118func (h *hmac) Size() int { return h.size }
119
120func (h *hmac) BlockSize() int { return h.blocksize }
121
122func (h *hmac) Reset() {
123 h.inner.Reset()
124 h.inner.Write(h.ipad)
125}