且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

将密码从web2py迁移到Django

更新时间:2023-09-13 17:43:28

根据这个 post 一个用于重新创建web2py中使用的约会的Python代码段将是以下内容:

  from hashlib import md5 
import hmac
hmac_key ='<你的密钥>'
password ='insecure'
thehash = hmac.new(hmac_key,password).hexdigest()
打印thehash

web2py使用hmac(这是您的秘密+用户密码的明文)作为最终哈希,而不仅仅是一个直接的MD5 / SHA哈希(取决于你的设置)。所以你只需要在上面的例子中换掉SHA的MD5,就可以让你的工作结束。但是这个实现是你需要在新应用程序中实现的,只要秘密密钥相同,就可以使它们交叉兼容。



根据 docs 哈希以以下格式存储:

 < algorithm> $< salt> $< hash> 

所以如果有一个盐,那么它与哈希存储,容易抓住盐在您的新应用程序中使用。美元符号可以方便地解析每个值。

  algo,salt,hash = password_hash.split($)

更新:我从web2py源中提取了以下代码,但您需要做的是更新变量hmac_key具有您为auth.settings.hmac_key设置的值。希望当你运行(更新hmac_key变量后)这个哈希应该匹配。

  import hashlib 
import hmac
from hashlib import sha512

h = sha512 $ b850ed44943b861b $ c90901439983bce7fd512592b20d83f8e654632dee51de515773e70eabe609f62cebec64fed4df03acd54e6a627c9291e70fdf3a89996ffa796897c159e95c11

algo,salt,hash = h.split($)
打印crypted hash:%s%hash

pwd =pawan123
##从auth.settings.hmac_key获取此值
hmac_key =

def get_digest(value):

从字符串返回一个hashlib摘要算法

如果不是isinstance(value,str):
返回值
value = value.lower()
如果值==md5:
返回md5
elif值==sha1:
返回sha1
elif值==sha224:
return sha224
elif value ==sha256:
return sha256
elif value ==sha384:
return sha384
elif value ==sha512
返回sha512
else:
raise ValueError(无效的摘要算法:%s%值)

#hashed = simple_hash(self.password,key,salt,digest_alg)
def simple_hash (text,key ='',salt ='',digest_alg ='md5')

使用指定的
生成与给定文本的散列哈希算法

如果不是digest_alg:
raise RuntimeError(simple_hash with digest_alg = None)
elif not isinstance(digest_alg,str):#manual approach
h = digest_alg text + key + salt)
elif digest_alg.startswith('pbkdf2'):#最新最酷!
iterations,keylen,alg = digest_alg [7:-1] .split(',')
返回pbkdf2_hex(文本,盐,int(迭代),
int(keylen),get_digest (alg))
elif key:#use hmac
digest_alg = get_digest(digest_alg)
h = hmac.new(key + salt,text,digest_alg)
else:#compatible第三方系统
h = get_digest(digest_alg)()
h.update(text + salt)
返回h.hexdigest()




printresult hash:%s%simple_hash(pwd,hmac_key,salt,sha512)


I have passwords stored in web2py using SHA 512 algorithm. I am now migrating the models to django and hence need a way to hash passwords in django using SHA 512 in the same way as web2py does so that I can authenticate the old users with the same passwords.Please suggest some way.

According to this post a Python snippet to recreate the convention used in web2py would be the following:

from hashlib import md5
import hmac
hmac_key = '<your secret key>'
password = 'insecure'
thehash = hmac.new(hmac_key, password).hexdigest()
print thehash

web2py uses hmac (which is your secret + the plaintext of the user's password) as the final hash and not just a straight MD5/SHA hash (depending on your settings). So you would just need to swap out MD5 for SHA in the above example to get things working on your end. But this implementation is all you would need to implement in your new application to make them cross compatible as long as the secret key is the same.

According to the docs the hash is stored in the following format:

    <algorithm>$<salt>$<hash>

so if there is a salt used then it's stored with the hash making it easy to grab the salt for use in your new application. The dollar signs make it easy to parse each value.

algo, salt, hash = password_hash.split("$")

UPDATE: I pulled the below code from the web2py source but what you need to do is update the variable hmac_key with the value that you have set for auth.settings.hmac_key. Hopefully when you run (after you update the hmac_key variable) this the hashes should match.

import hashlib
import hmac
from hashlib import sha512

h="sha512$b850ed44943b861b$c90901439983bce7fd512592b20d83f8e654632dee51de515773e70eabe609f62cebec64fed4df03acd54e6a627c9291e70fdf3a89996ffa796897c159e95c11"

algo,salt,hash = h.split("$")
print "crypted hash: %s"%hash

pwd = "pawan123"
##get this value from auth.settings.hmac_key
hmac_key = "" 

def get_digest(value):
    """
    Returns a hashlib digest algorithm from a string
    """
    if not isinstance(value, str):
        return value
    value = value.lower()
    if value == "md5":
        return md5
    elif value == "sha1":
        return sha1
    elif value == "sha224":
        return sha224
    elif value == "sha256":
        return sha256
    elif value == "sha384":
        return sha384
    elif value == "sha512":
        return sha512
    else:
        raise ValueError("Invalid digest algorithm: %s" % value)

#hashed = simple_hash(self.password, key, salt, digest_alg)
def simple_hash(text, key='', salt='', digest_alg='md5'):
    """
    Generates hash with the given text using the specified
    digest hashing algorithm
    """
    if not digest_alg:
        raise RuntimeError("simple_hash with digest_alg=None")
    elif not isinstance(digest_alg, str):  # manual approach
        h = digest_alg(text + key + salt)
    elif digest_alg.startswith('pbkdf2'):  # latest and coolest!
        iterations, keylen, alg = digest_alg[7:-1].split(',')
        return pbkdf2_hex(text, salt, int(iterations),
                          int(keylen), get_digest(alg))
    elif key:  # use hmac
        digest_alg = get_digest(digest_alg)
        h = hmac.new(key + salt, text, digest_alg)
    else:  # compatible with third party systems
        h = get_digest(digest_alg)()
        h.update(text + salt)
    return h.hexdigest()




print "result hash:  %s"%simple_hash(pwd, hmac_key, salt, "sha512")