1456
|
1 local hashes = require "util.hashes"
|
|
2 local xor = require "bit".bxor
|
|
3
|
|
4 module "hmac"
|
|
5
|
|
6 local function arraystr(array)
|
|
7 t = {}
|
|
8 for i = 1,table.getn(array) do
|
|
9 table.insert(t, string.char(array[i]))
|
|
10 end
|
|
11
|
|
12 return table.concat(t)
|
|
13 end
|
|
14
|
|
15 --[[
|
|
16 key
|
|
17 the key to use in the hash
|
|
18 message
|
|
19 the message to hash
|
|
20 hash
|
|
21 the hash function
|
|
22 blocksize
|
|
23 the blocksize for the hash function in bytes
|
|
24 hex
|
|
25 return raw hash or hexadecimal string
|
|
26 --]]
|
|
27 function hmac(key, message, hash, blocksize, hex)
|
|
28 local opad = {}
|
|
29 local ipad = {}
|
|
30
|
|
31 for i = 1,blocksize do
|
|
32 opad[i] = 0x5c
|
|
33 ipad[i] = 0x36
|
|
34 end
|
|
35
|
|
36 if #key > blocksize then
|
|
37 key = hash(key)
|
|
38 end
|
|
39
|
|
40 for i = 1,#key do
|
|
41 ipad[i] = xor(ipad[i],key:sub(i,i):byte())
|
|
42 opad[i] = xor(opad[i],key:sub(i,i):byte())
|
|
43 end
|
|
44
|
|
45 opad = arraystr(opad)
|
|
46 ipad = arraystr(ipad)
|
|
47
|
|
48 if hex then
|
|
49 return hash(opad..hash(ipad..message), true)
|
|
50 else
|
|
51 return hash(opad..hash(ipad..message))
|
|
52 end
|
|
53 end
|
|
54
|
|
55 function md5(key, message, hex)
|
|
56 return hmac(key, message, hashes.md5, 64, hex)
|
|
57 end
|
|
58
|
|
59 function sha1(key, message, hex)
|
|
60 return hmac(key, message, hashes.sha1, 64, hex)
|
|
61 end
|
|
62
|
|
63 function sha256(key, message, hex)
|
|
64 return hmac(key, message, hashes.sha256, 64, hex)
|
|
65 end
|
|
66
|
|
67 return _M
|