公共代码:

#!/usr/bin/env python
# -*- encoding:utf-8 -*-

import hashlib

user= "12345"
now = 1388653051.12

def md5( s ):
    m = hashlib.md5()
    m.update(s)
    return m.hexdigest()

如果我们要对某个帐号生成校验码和生成时间,一般的方案是:

s = md5(user + str(now))
s+=  "." + str(now)
print s #9789526c5db4b97a5a41824ba91ec1f2.1388653051.12

然后我们就会发现,当对前面的32位进行反查md5的时候很容易得到原始的 "12345"
于是我们继续混淆,把时间先md5一下然后再总体md5

now_md5_hex = md5((str(now)))
s = md5(user + now_md5_hex)
s+="." + str(now)
print s  #5e31cc8cac2e1d3e33e6a8637fa76115.1388653051.12

反查还是有点简单,我们决定对时间的md5值进行取样,取前4位(当然也可以取1,3,5,7位)

now_md5_hex = md5((str(now)))
s = md5(user + now_md5_hex[0:4])
s+="." + str(now)
print s  #a658d7fddaf0d4f49551837b476c5269.1388653051.12

一般人的方案到这里就结束了,如果有加强,可能不是取前4位而已,取的是[1,3,4,7]这样的位,不管怎样,取多少位都是写死在程序里的。如果你说引入第三个变量,效果是一样的..因为时间这个变量是要给客户端的...

于是我们想,时间戳还有没有其它利用价值,好吧,原来时间也是数字,我们根据时间每个位每个字符,于是诞生了如下的想法:

s = md5(user)
now_str = str(int(now))
rnd = [s[int(i)] for i in now_str]
s = md5(s + ("".join(rnd)))
s+="." + str(now)
print s  #c3827f2499d5794d2b2071b7be7c890b.1388653051.12

感觉这样还是有点容易了,想了想,时间还有什么作用,时间线性同余随机数,不多解释,上代码了:

import random
rdm = random.Random()
rdm.seed(now)
s = md5(user)
rnd = [str(rdm.randint(1,100)) for i in range(0,4)]
s = md5(s + ("".join(rnd)))
s+="." + str(now)
print s  #89fa3b1dfdd624357320f5496a7cb07c.1388653051.12

好了...到这里已经有点难度了把... 如果前面四种进行随机组合和叠加,那就更难破解了...


罗音
2k 声望31 粉丝

引用和评论

0 条评论