알고리즘에 대한 Python 3.8.3 hashlib에 해시 알고리즘이 있습니까? Base64 (SHA1 (NONCE + TIMESTAMP + SHA1 (PASSWORD)))?

Oct 07 2020

먼저 사과드립니다, 여기 초보자는 Pythonic 여행을 시작하고 내가 직면하고있는이 작은 문제를 제외하고 지금까지 즐기고 있습니다.

암호 다이제스트를 위해 Python의 hashlib 및 base64 라이브러리를 사용하여 일부 값을 이중 해시 (SHA1) 및 base64로 인코딩하는 방법을 찾으려고 노력했지만 막혔습니다.

다음 알고리즘을 사용하는 요약 된 암호로 SOAP XML 웹 서비스 헤더를 채워야합니다. Base64 (SHA1 (NONCE + TIMESTAMP + SHA1 (PASSWORD)))

아래 문서에서 발췌 한 내용은 올바른 결과와 몇 가지 일반적인 오류를 보여줍니다.

QUOTE 입력 매개 변수 :

일반 텍스트 비밀번호 : AMADEUS

Raw Nonce (인쇄 불가능할 수 있음) : secretnonce10111

Base64 인코딩 Nonce : c2VjcmV0bm9uY2UxMDExMQ ==

타임 스탬프 / 작성일 : 2015-09-30T14 : 12 : 15Z

  1. 올바른 결과 : 암호 다이제스트 : + LzcaRc + ndGAcZIXmq / N7xGes + k = 수식 : Base64 (SHA1 ($NONCE + $타임 스탬프 + SHA1 ($ CLEARPASSWORD)))

  2. Nonce XML 요소에서와 동일한 (Base64) 형식을 갖는 $ NONCE를 제외한 모든 매개 변수가 올 바릅니다. 비밀번호 다이제스트 : AiRk9oAVpkYDX2MXh + diClQ0Lds = Formula : Base64 (SHA1 (Base64 ($NONCE) + $타임 스탬프 + SHA1 ($ CLEARPASSWORD)))

  3. 초기 일반 암호 암호화 및 연결된 문자열에 대한 원시 SHA1 대신 16 진수 인코딩의 SHA1 : 암호 다이제스트 : NWE1MGRhM2ZmNjFhMDA2ODUyNmIxMGM4MTczODQ0NjE2MWQyM2IxZQ == 수식 : Base64 (HEX (SHA1 ($ NONCE) + $TIMESTAMP + HEX(SHA1($CLEARPASSWORD))))

  4. 연결된 문자열에 대한 원시 SHA1 대신 16 진수 인코딩의 SHA1, SHA1로 암호화되지 않은 암호 : 암호 다이제스트 : NzU0ZjJlMTc2ZjkxZmM2OTg4N2E0ZDlkMWY2MWE0YWJkOGI0MzYxZA == 수식 : Base64 (HEX (SHA1 ($NONCE + $타임 스탬프 + $ CLEARPASSWORD)))

  5. 거의 모든 것이 잘못되었습니다. 연결된 문자열에 대한 원시 SHA1 대신 16 진수 인코딩의 SHA1, SHA1로 암호화되지 않은 암호, $ NONCE는 Nonce XML 요소에서와 동일한 (Base64) 형식을 갖습니다. 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 대신 16 진수 인코딩의 SHA1"때문에 작동하지 않습니다.

위 코드에서 해시를 16 진수로 변환하는 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에 직접 바이트 값을 입력하려고 시도했지만 기쁨이 없습니다 ...

많은 질문이 있지만 가장 중요한 질문은 다음과 같습니다. 내가 뭘 놓치고 있니? 이를 수행 할 수있는 우아한 방법이 있습니까? "raw SHA1"또는 "bytes-like objects"값을 문자열과 연결할 수 있습니까?

답변

FrankYellin Oct 07 2020 at 05:07

지침이 당신에게 무엇을 말하고 있는지 이해하지 못하지만 hexdigest()대신에 를 사용하는 digest()것은 거의 틀림없이 실수입니다. 암호로 작업 할 때 거의 항상 문자열이 아닌 바이트를 처리합니다. 바이트 문자열 (텍스트, nonce, 타임 스탬프)이 아닌 모든 것은 바이트 문자열로 변환되어야합니다. 모든 계산 및 연결은이 바이트 문자열로 수행되어야합니다. 그리고 마지막 단계로 필요한 경우 다시 문자열로 변환합니다.

SteveLawrence Oct 07 2020 at 16:41

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 ())

print (type (PWDIGEST), PWDIGEST) <class 'bytes'> b '+ LzcaRc + ndGAcZIXmq / N7xGes + k ='

팔!