首先向大家道歉,作为新手我开始了我的Python之旅,并且迄今为止非常喜欢它,除了我现在遇到的这个小问题...
我一直在尝试使用Python的hashlib和base64库找到双散列(SHA1)和Base64编码一些值的方法,用于密码摘要,但我卡住了。
我需要使用以下算法填充SOAP XML web服务头,以使用摘要密码; Base64(SHA1(NONCE + TIMESTAMP + SHA1(PASSWORD)))
下面是文档的摘录,显示了正确的结果和一些常见错误:
引言 输入参数:
纯文本密码: AMADEUS
原始Nonce(可能无法打印):secretnonce10111
Base64编码的Nonce: c2VjcmV0bm9uY2UxMDExMQ==
时间戳/创建时间: 2015-09-30T14:12:15Z
正确的结果: 密码摘要:+LzcaRc+ndGAcZIXmq/N7xGes+k= 公式:Base64(SHA1($NONCE + $TIMESTAMP + SHA1($CLEARPASSWORD)))
所有参数正确,除了$NONCE与Nonce XML元素中相同的(Base64)格式外: 密码摘要:AiRk9oAVpkYDX2MXh+diClQ0Lds= 公式:Base64(SHA1(Base64($NONCE) + $TIMESTAMP + SHA1($CLEARPASSWORD)))
初始明文密码加密和连接字符串使用十六进制编码的SHA1,而不是原始SHA1: 密码摘要:NWE1MGRhM2ZmNjFhMDA2ODUyNmIxMGM4MTczODQ0NjE2MWQyM2IxZQ== 公式:Base64(HEX(SHA1($NONCE) + $TIMESTAMP + HEX(SHA1($CLEARPASSWORD))))
连接字符串使用十六进制编码的SHA1,密码没有使用SHA1进行加密: 密码摘要:NzU0ZjJlMTc2ZjkxZmM2OTg4N2E0ZDlkMWY2MWE0YWJkOGI0MzYxZA== 公式:Base64(HEX(SHA1($NONCE + $TIMESTAMP + $CLEARPASSWORD)))
几乎所有东西都是错误的:连接字符串使用十六进制编码的SHA1,密码没有使用SHA1进行加密,$NONCE与Nonce XML元素中相同的(Base64)格式: 密码摘要:NGIzYmNiY2I3Njc2ZjZiNzdmNDMwMGVlMTIwODdhZDE1ZmZlOTEwMA== 公式:Base64(HEX(SHA1(Base64($NONCE) + $TIMESTAMP + $CLEARPASSWORD))) UNQUOTE
这是我目前的翻译,按照文档建议使用变量以便检查结果。
import base64
import hashlib
NONCE = "secretnonce10111"
TIMESTAMP = "2015-09-30T14:12:15Z"
PASSWORD = "AMADEUS"
PWSHA1 = hashlib.sha1(PASSWORD.encode('ascii')).hexdigest()
CONCAT = (NONCE + TIMESTAMP + str(PWSHA1)).encode('ascii')
CONCATSHA1 = hashlib.sha1(CONCAT).hexdigest()
PWDIGEST = base64.b64encode(CONCATSHA1.encode('ascii')).decode('ascii')
print(type(PWDIGEST), PWDIGEST)
结果
<class 'str'> NWE1MGRhM2ZmNjFhMDA2ODUyNmIxMGM4MTczODQ0NjE2MWQyM2IxZQ==
注意:我已经使用了编码方式为utf-8和ascii的以及空白的代码,还写了一个更简洁的版本但是并没有成功...
PWDIGEST = base64.b64encode(hashlib.sha1((NONCE + TIMESTAMP + str(hashlib.sha1(PASSWORD.encode('ascii')).hexdigest())).encode('ascii')).hexdigest().encode('ascii')).decode('ascii')
如你所见,根据文档,它无法工作的原因是“初始纯文本密码加密和连接字符串的哈希使用十六进制编码的SHA1而不是原始SHA1”。
我意识到我在上面的代码中使用了hexdigest(),它将哈希渲染为十六进制,但这是我能得到的最接近的结果。
遵循Python hashlib文档,我也尝试过使用.digest()和update(),但是结果完全不同于文档中的内容,如下所示:
PWSHA = hashlib.sha1()
PWSHA.update(PASSWORD.encode('utf-8'))
PWSHA1 = PWSHA.digest()
CONCAT = (NONCE + TIMESTAMP + str(PWSHA1))
CSHA = hashlib.sha1()
CSHA.update(CONCAT.encode("utf-8"))
CSHA1 = CSHA.digest()
PWDIGEST = base64.b64encode(CSHA1).decode('ascii')
print(type(PWDIGEST), PWDIGEST)
结果
<class 'str'> exB8TjilUE+w8b2SKs+PkOhRjfg=
我也尝试过直接将字节值输入到base64.b64encode中,但没有成功...
我有很多问题,但我想最重要的问题是:我错过了什么?是否有一种优雅的方式可以完成这项任务?是否可能将“原始SHA1”或“类似字节对象”的值与字符串连接起来?