Md5padding
hash长度扩展攻击¶
- 知道secret的长度和hash
- 求出(SECRET+PADDING+EXTRA)的哈希
tool¶
# coding:utf-8
import sys
import struct
import hashlib
import binascii
def F(x, y, z):
return (x & y) | ((~x) & z)
def G(x, y, z):
return (x & z) | (y & (~z))
def H(x, y, z):
return x ^ y ^ z
def I(x, y, z):
return y ^ (x | (~z))
def _rotateLeft( x, n):
return (x << n) | (x >> (32-n))
def XX(func, a, b, c, d, x, s, ac):
res = 0L
res = res + a + func(b, c, d)
res = res + x
res = res + ac
res = res & 0xffffffffL
res = _rotateLeft(res, s)
res = res & 0xffffffffL
res = res + b
return res & 0xffffffffL
class md5():
def __init__(self):
self.A, self.B, self.C, self.D = (0x67452301L, 0xefcdab89L, 0x98badcfeL, 0x10325476L)
def md5_compress(self, buf):
if len(buf) != 64:
raise ValueError, "Invalid buffer of length %d: %s" % (len(buf), repr(buf))
inp = struct.unpack("I"*16, buf)
a, b, c, d = self.A, self.B, self.C, self.D
# Round 1.
S11, S12, S13, S14 = 7, 12, 17, 22
a = XX(F, a, b, c, d, inp[0], S11, 0xD76AA478L) # 1
d = XX(F, d, a, b, c, inp[1], S12, 0xE8C7B756L) # 2
c = XX(F, c, d, a, b, inp[2], S13, 0x242070DBL) # 3
b = XX(F, b, c, d, a, inp[3], S14, 0xC1BDCEEEL) # 4
a = XX(F, a, b, c, d, inp[4], S11, 0xF57C0FAFL) # 5
d = XX(F, d, a, b, c, inp[5], S12, 0x4787C62AL) # 6
c = XX(F, c, d, a, b, inp[6], S13, 0xA8304613L) # 7
b = XX(F, b, c, d, a, inp[7], S14, 0xFD469501L) # 8
a = XX(F, a, b, c, d, inp[8], S11, 0x698098D8L) # 9
d = XX(F, d, a, b, c, inp[9], S12, 0x8B44F7AFL) # 10
c = XX(F, c, d, a, b, inp[10], S13, 0xFFFF5BB1L) # 11
b = XX(F, b, c, d, a, inp[11], S14, 0x895CD7BEL) # 12
a = XX(F, a, b, c, d, inp[12], S11, 0x6B901122L) # 13
d = XX(F, d, a, b, c, inp[13], S12, 0xFD987193L) # 14
c = XX(F, c, d, a, b, inp[14], S13, 0xA679438EL) # 15
b = XX(F, b, c, d, a, inp[15], S14, 0x49B40821L) # 16
# Round 2.
S21, S22, S23, S24 = 5, 9, 14, 20
a = XX(G, a, b, c, d, inp[1], S21, 0xF61E2562L) # 17
d = XX(G, d, a, b, c, inp[6], S22, 0xC040B340L) # 18
c = XX(G, c, d, a, b, inp[11], S23, 0x265E5A51L) # 19
b = XX(G, b, c, d, a, inp[0], S24, 0xE9B6C7AAL) # 20
a = XX(G, a, b, c, d, inp[5], S21, 0xD62F105DL) # 21
d = XX(G, d, a, b, c, inp[10], S22, 0x02441453L) # 22
c = XX(G, c, d, a, b, inp[15], S23, 0xD8A1E681L) # 23
b = XX(G, b, c, d, a, inp[4], S24, 0xE7D3FBC8L) # 24
a = XX(G, a, b, c, d, inp[9], S21, 0x21E1CDE6L) # 25
d = XX(G, d, a, b, c, inp[14], S22, 0xC33707D6L) # 26
c = XX(G, c, d, a, b, inp[3], S23, 0xF4D50D87L) # 27
b = XX(G, b, c, d, a, inp[8], S24, 0x455A14EDL) # 28
a = XX(G, a, b, c, d, inp[13], S21, 0xA9E3E905L) # 29
d = XX(G, d, a, b, c, inp[2], S22, 0xFCEFA3F8L) # 30
c = XX(G, c, d, a, b, inp[7], S23, 0x676F02D9L) # 31
b = XX(G, b, c, d, a, inp[12], S24, 0x8D2A4C8AL) # 32
# Round 3.
S31, S32, S33, S34 = 4, 11, 16, 23
a = XX(H, a, b, c, d, inp[5], S31, 0xFFFA3942L) # 33
d = XX(H, d, a, b, c, inp[8], S32, 0x8771F681L) # 34
c = XX(H, c, d, a, b, inp[11], S33, 0x6D9D6122L) # 35
b = XX(H, b, c, d, a, inp[14], S34, 0xFDE5380CL) # 36
a = XX(H, a, b, c, d, inp[1], S31, 0xA4BEEA44L) # 37
d = XX(H, d, a, b, c, inp[4], S32, 0x4BDECFA9L) # 38
c = XX(H, c, d, a, b, inp[7], S33, 0xF6BB4B60L) # 39
b = XX(H, b, c, d, a, inp[10], S34, 0xBEBFBC70L) # 40
a = XX(H, a, b, c, d, inp[13], S31, 0x289B7EC6L) # 41
d = XX(H, d, a, b, c, inp[0], S32, 0xEAA127FAL) # 42
c = XX(H, c, d, a, b, inp[3], S33, 0xD4EF3085L) # 43
b = XX(H, b, c, d, a, inp[6], S34, 0x04881D05L) # 44
a = XX(H, a, b, c, d, inp[9], S31, 0xD9D4D039L) # 45
d = XX(H, d, a, b, c, inp[12], S32, 0xE6DB99E5L) # 46
c = XX(H, c, d, a, b, inp[15], S33, 0x1FA27CF8L) # 47
b = XX(H, b, c, d, a, inp[2], S34, 0xC4AC5665L) # 48
# Round 4.
S41, S42, S43, S44 = 6, 10, 15, 21
a = XX(I, a, b, c, d, inp[0], S41, 0xF4292244L) # 49
d = XX(I, d, a, b, c, inp[7], S42, 0x432AFF97L) # 50
c = XX(I, c, d, a, b, inp[14], S43, 0xAB9423A7L) # 51
b = XX(I, b, c, d, a, inp[5], S44, 0xFC93A039L) # 52
a = XX(I, a, b, c, d, inp[12], S41, 0x655B59C3L) # 53
d = XX(I, d, a, b, c, inp[3], S42, 0x8F0CCC92L) # 54
c = XX(I, c, d, a, b, inp[10], S43, 0xFFEFF47DL) # 55
b = XX(I, b, c, d, a, inp[1], S44, 0x85845DD1L) # 56
a = XX(I, a, b, c, d, inp[8], S41, 0x6FA87E4FL) # 57
d = XX(I, d, a, b, c, inp[15], S42, 0xFE2CE6E0L) # 58
c = XX(I, c, d, a, b, inp[6], S43, 0xA3014314L) # 59
b = XX(I, b, c, d, a, inp[13], S44, 0x4E0811A1L) # 60
a = XX(I, a, b, c, d, inp[4], S41, 0xF7537E82L) # 61
d = XX(I, d, a, b, c, inp[11], S42, 0xBD3AF235L) # 62
c = XX(I, c, d, a, b, inp[2], S43, 0x2AD7D2BBL) # 63
b = XX(I, b, c, d, a, inp[9], S44, 0xEB86D391L) # 64
self.A = (self.A + a) & 0xffffffffL
self.B = (self.B + b) & 0xffffffffL
self.C = (self.C + c) & 0xffffffffL
self.D = (self.D + d) & 0xffffffffL
# print 'A=%s\nB=%s\nC=%s\nD=%s\n' % (hex(self.A), hex(self.B), hex(self.C), hex(self.D))
def padding(self, n, sz=None):
if sz is None:
sz = n
pre = 64-8
sz = struct.pack("Q",sz*8)
pad = '\x80'
n += 1
if n % 64 <= pre:
pad += '\x00' * (pre - n % 64)
pad += sz
else:
pad += '\x00' * (pre + 64 - n % 64)
pad += sz
return pad
def pad(self, msg):
return msg + self.padding(len(msg))
def md5_iter(self, padding_msg):
assert len(padding_msg) % 64 == 0
for i in range(0, len(padding_msg), 64):
block = padding_msg[i:i+64]
self.md5_compress(padding_msg[i:i+64])
def digest(self):
return struct.pack('<IIII', self.A, self.B, self.C, self.D) def hexdigest(self): return binascii.hexlify(self.digest()).decode() def my_md5(self, msg): padding_msg = self.pad(msg) self.md5_iter(padding_msg) return self.hexdigest() # 通过md5值,逆向算出最后一轮的magic number def compute_magic_number(self, md5str): self.A = struct.unpack("I", md5str[0:8].decode('hex'))[0] self.B = struct.unpack("I", md5str[8:16].decode('hex'))[0] self.C = struct.unpack("I", md5str[16:24].decode('hex'))[0] self.D = struct.unpack("I", md5str[24:32].decode('hex'))[0] #print 'A=%s\nB=%s\nC=%s\nD=%s\n' % (hex(self.A), hex(self.B), hex(self.C), hex(self.D)) def extension_attack(self, md5str, str_append, lenth): self.compute_magic_number(md5str) p = self.padding(lenth) padding_msg = self.padding( len(str_append), lenth + len(p) + len(str_append) ) self.md5_iter(str_append + padding_msg) return self.hexdigest() if __name__ == "__main__": m = md5() if len(sys.argv) != 4: #print m.my_md5("123456") src = m.pad(sys.argv[1]) + sys.argv[2] print 'md5 padding ->',m.my_md5(src)
else:
print 'md5 extension_attack ->',m.extension_attack(sys.argv[1], sys.argv[2], int(sys.argv[3]))
本页面的全部内容在 CC BY-NC-SA 4.0 协议之条款下提供,附加条款亦可能应用。