Python能否将字符串编码以匹配ASP.NET会员提供者的EncodePassword?

1 投票
1 回答
1044 浏览
提问于 2025-04-15 14:29

我正在写一个Python脚本,目的是从一个类似于ASP.NET的MembershipProvider的系统中创建哈希字符串。用Python的话,有没有办法把一个十六进制字符串转换回二进制,然后再进行base64编码,同时把原始字符串当作Unicode来处理呢?我们来试试一些代码。我想重新编码一个哈希密码,这样在Python和ASP.NET/C#中得到的哈希值是一样的:

import base64
import sha
import binascii

def EncodePassword(password):
    # strings are currently stored as hex
    hex_hashed_password = sha.sha(password).hexdigest()

    # attempt to convert hex to base64
    bin_hashed_password = binascii.unhexlify(hex_hashed_password)
    return base64.standard_b64encode(bin_hashed_password)

print EncodePassword("password")
# W6ph5Mm5Pz8GgiULbPgzG37mj9g=

ASP.NET的MembershipProvider使用这个方法来编码:

static string EncodePassword(string pass)
{
    byte[] bytes = Encoding.Unicode.GetBytes(pass);
    //bytes = Encoding.ASCII.GetBytes(pass);

    byte[] inArray = null;
    HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
    inArray = algorithm.ComputeHash(bytes);
    return Convert.ToBase64String(inArray);
}

string s = EncodePassword("password");
// 6Pl/upEE0epQR5SObftn+s2fW3M=

但是结果不一样。不过,当我用ASCII编码的密码运行时,结果是匹配的,所以.NET方法中的Unicode部分就是不同之处。

W6ph5Mm5Pz8GgiULbPgzG37mj9g=

在Python脚本中,有没有办法得到一个与默认.NET版本匹配的输出呢?

1 个回答

5

这里有个小窍门:

Encoding.Unicode

“Unicode”编码其实是微软用的一个术语,指的是UTF-16LE(特别是没有字节顺序标记BOM)。在进行哈希处理之前,先把字符串编码成这个格式,你就能得到正确的结果:

>>> import hashlib
>>> p= u'password'
>>> hashlib.sha1(p.encode('utf-16le')).digest().encode('base64')
'6Pl/upEE0epQR5SObftn+s2fW3M=\n'

撰写回答