簡體   English   中英

該算法在Python 3.8.3 hashlib中是否有Hash算法; Base64(SHA1(隨機數 + 時間戳 + SHA1(密碼)))?

[英]Is there a Hash algorithm in Python 3.8.3 hashlib for the algorithm; Base64(SHA1(NONCE + TIMESTAMP + SHA1(PASSWORD)))?

首先道歉,這里的新手剛剛開始我的 Pythonic 之旅,並且到目前為止還很享受,除了我面臨的這個小問題......

我一直在嘗試找到一種方法,使用 Python 的 hashlib 和 base64 庫對一些值進行雙哈希(SHA1)和 base64 編碼,以獲取密碼摘要,但我被卡住了。

我需要使用使用以下算法的摘要密碼填充 SOAP XML Web 服務標頭; Base64(SHA1(NONCE + TIMESTAMP + SHA1(PASSWORD)))

下面的文檔摘錄顯示了正確的結果和一些常見錯誤:

QUOTE 輸入參數:

純文本密碼:AMADEUS

原始隨機數(可能無法打印):secretnonce10111

Base64 編碼的 Nonce:c2VjcmV0bm9uY2UxMDExMQ==

時間戳/創建時間:2015-09-30T14:12:15Z

  1. 正確結果: 密碼摘要:+LzcaRc+ndGAcZIXmq/N7xGes+k= 公式:Base64(SHA1($NONCE + $TIMESTAMP + SHA1($CLEARPASSWORD)))

  2. 所有參數都正確,除了 $NONCE 具有與 Nonce XML 元素相同的 (Base64) 格式:密碼摘要:AiRk9oAVpkYDX2MXh+diClQ0Lds= 公式:Base64(SHA1(Base64($NONCE) + $TIMESTAMP + SHA1($CLEARPASSWORD)))

  3. 十六進制編碼的 SHA1 而不是原始 SHA1,用於初始純密碼加密和連接字符串:密碼摘要:NWE1MGRhM2ZmNjFhMDA2ODUyNmIxMGM4MTczODQ0NjE2MWQyM2IxZQ== 公式:Base64(HEX(SHA1($NONCE)+ARPCLE) +

  4. 十六進制編碼的 SHA1 而不是原始 SHA1 用於連接字符串,密碼未使用 SHA1 加密:密碼摘要:NzU0ZjJlMTc2ZjkxZmM2OTg4N2E0ZDlkMWY2MWE0YWJkOGI0MzYxZA== 公式:Base64(HEX(HEX($TIME$STAMP)) +

  5. 幾乎所有內容都是不正確的:十六進制編碼中的 SHA1 而不是用於連接字符串的原始 SHA1,密碼未使用 SHA1 加密,$NONCE 具有與 Nonce XML 元素相同的 (Base64) 格式:密碼摘要:NGIzYmNiY2I3Njc2ZjZiNzdmNDMwMGVlMTIwODdhZOTE6(Formula SHA1(Base64($NONCE) + $TIMESTAMP + $CLEARPASSWORD))) 取消引用

這是我到目前為止所擁有的,使用文檔中建議的變量,以便我可以檢查結果:

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”或“類似字節的對象”值與字符串連接起來?

我不明白指令告訴你做什么,但你使用hexdigest()而不是digest()幾乎肯定是一個錯誤。 當您使用加密時,您幾乎總是在處理字節,而不是字符串。 不是字節字符串的所有內容(文本、隨機數、時間戳)都應轉換為字節字符串。 所有計算和連接都應該用這個字節串來完成。 然后作為最后一步,如有必要,將其轉換回字符串。

感謝 Frank Yellin 的指點,我能夠通過將算法中的所有值轉換為字節來解決這個問題,如下所示:

TIMESTAMPB = TIMESTAMP.encode('utf8')

NONCEB = NONCE.encode('utf8')

CONCAT = NONCEB + TIMESTAMPB + PWSHA1

CSHA = hashlib.sha1()

CSHA.update(CONCAT)

PWDIGEST = base64.b64encode(CSHA.digest())

打印(類型(PWDIGEST),PWDIGEST)<class 'bytes'> b'+LzcaRc+ndGAcZIXmq/N7xGes+k='

繁榮!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM