生成忘記密碼校驗碼的那些故事

公共代碼:python

#!/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()

若是咱們要對某個賬號生成校驗碼和生成時間,通常的方案是:dom

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

而後咱們就會發現,當對前面的32位進行反查md5的時候很容易獲得原始的 "12345"
因而咱們繼續混淆,把時間先md5一下而後再整體md5code

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位)md5

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]這樣的位,無論怎樣,取多少位都是寫死在程序裏的。若是你說引入第三個變量,效果是同樣的..由於時間這個變量是要給客戶端的...utf-8

因而咱們想,時間戳還有沒有其它利用價值,好吧,原來時間也是數字,咱們根據時間每一個位每一個字符,因而誕生了以下的想法:hash

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

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

好了...到這裏已經有點難度了把... 若是前面四種進行隨機組合和疊加,那就更難破解了...變量

相關文章
相關標籤/搜索