9

अमेज़ॅन आईओएस, एंड्रॉइड, और जावास्क्रिप्ट कॉग्निटो एसडीके प्रदान करता है जो उच्च स्तरीय प्रमाणीकरण-उपयोगकर्ता ऑपरेशन प्रदान करता है, के लिए python boto3 के साथ USER_SRP_AUTH को कार्यान्वित करता है। cognito.initiate_auth और cognito.respond_to_auth_challenge:AWS Cognito

https://github.com/aws/amazon-cognito-identity-js

हालांकि, अगर आप अजगर/boto3 उपयोग कर रहे हैं, तुम सब मिल पुरातन की एक जोड़ी हैं:

उदाहरण के लिए, प्रकरण का प्रयोग करें यहाँ 4 देखें।

मैं इन प्राइमेटिव्स को pysrp lib के साथ USER_SRP_AUTH प्रवाह के साथ प्रमाणीकृत करने का प्रयास कर रहा हूं, लेकिन मेरे पास जो काम नहीं है, वह काम नहीं कर रहा है।

यह हमेशा "विफल त्रुटि (NotAuthorizedException) के साथ विफल रहता है जब RespondToAuthChallenge ऑपरेशन को कॉल करते समय: गलत उपयोगकर्ता नाम या पासवर्ड।" (उपयोगकर्ता नाम/पासवर्ड जोड़ी काम जेएस एसडीके के साथ मिलते हैं।)

मेरा संदेह है कि मैं चुनौती प्रतिक्रिया गलत (चरण 3) का निर्माण कर रहा हूं, और/या बेसिट 64 या इसके विपरीत होने पर कांगिटो हेक्स स्ट्रिंग को पास कर रहा हूं।

क्या किसी ने यह काम किया है? कोई भी देखता है कि मैं क्या गलत कर रहा हूं?

मैं authenticateUser कॉल जावास्क्रिप्ट एसडीके में पाए जाने वाले व्यवहार को कॉपी करने की कोशिश कर रहा हूँ:

https://github.com/aws/amazon-cognito-identity-js/blob/master/src/CognitoUser.js#L138

लेकिन मैं कुछ गलत कर रहा हूँ और क्या को समझ नहीं सकता।

#!/usr/bin/env python 
import base64 
import binascii 
import boto3 
import datetime as dt 
import hashlib 
import hmac 

# http://pythonhosted.org/srp/ 
# https://github.com/cocagne/pysrp 
import srp 

bytes_to_hex = lambda x: "".join("{:02x}".format(ord(c)) for c in x) 

cognito = boto3.client('cognito-idp', region_name="us-east-1") 

username = "[email protected]" 
password = "123456" 

user_pool_id = u"us-east-1_XXXXXXXXX" 
client_id = u"XXXXXXXXXXXXXXXXXXXXXXXXXX" 

# Step 1: 
# Use SRP lib to construct a SRP_A value. 

srp_user = srp.User(username, password) 
_, srp_a_bytes = srp_user.start_authentication() 

srp_a_hex = bytes_to_hex(srp_a_bytes) 

# Step 2: 
# Submit USERNAME & SRP_A to Cognito, get challenge. 

response = cognito.initiate_auth(
    AuthFlow='USER_SRP_AUTH', 
    AuthParameters={ 'USERNAME': username, 'SRP_A': srp_a_hex }, 
    ClientId=client_id, 
    ClientMetadata={ 'UserPoolId': user_pool_id }) 

# Step 3: 
# Use challenge parameters from Cognito to construct 
# challenge response. 

salt_hex   = response['ChallengeParameters']['SALT'] 
srp_b_hex  = response['ChallengeParameters']['SRP_B'] 
secret_block_b64 = response['ChallengeParameters']['SECRET_BLOCK'] 

secret_block_bytes = base64.standard_b64decode(secret_block_b64) 
secret_block_hex = bytes_to_hex(secret_block_bytes) 

salt_bytes = binascii.unhexlify(salt_hex) 
srp_b_bytes = binascii.unhexlify(srp_b_hex) 

process_challenge_bytes = srp_user.process_challenge(salt_bytes,       
                srp_b_bytes) 

timestamp = unicode(dt.datetime.utcnow().strftime("%a %b %d %H:%m:%S +0000 %Y")) 

hmac_obj = hmac.new(process_challenge_bytes, digestmod=hashlib.sha256) 
hmac_obj.update(user_pool_id.split('_')[1].encode('utf-8')) 
hmac_obj.update(username.encode('utf-8')) 
hmac_obj.update(secret_block_bytes) 
hmac_obj.update(timestamp.encode('utf-8')) 

challenge_responses = { 
    "TIMESTAMP": timestamp.encode('utf-8'), 
    "USERNAME": username.encode('utf-8'), 
    "PASSWORD_CLAIM_SECRET_BLOCK": secret_block_hex, 
    "PASSWORD_CLAIM_SIGNATURE": hmac_obj.hexdigest() 
} 

# Step 4: 
# Submit challenge response to Cognito. 

response = cognito.respond_to_auth_challenge(
    ClientId=client_id, 
    ChallengeName='PASSWORD_VERIFIER', 
    ChallengeResponses=challenge_responses) 
+0

क्या आपने कभी यह काम किया है? मैं अपनी परियोजना में एक ही चीज़ पर काम कर रहा हूं। – man2xxl

+0

नहीं, मैंने थोड़ा आगे टक्कर लगी, लेकिन अब तक कोई भाग्य नहीं है। एक काम के रूप में, मैंने एक कस्टम-ऑथ लैम्ब्डा ('DefineAuthChallenge') स्थापित किया है जो हमेशा उपयोगकर्ता को लेखक बनाता है: 'export.handler = function (event, context) {event.response.issueTokens = true; event.response.fail प्रमाणीकरण = झूठा; context.done (शून्य, घटना);} '। यह सब मुझे अभी चाहिए क्योंकि मैं सिर्फ प्रोटोटाइप का निर्माण कर रहा हूं। लेकिन मैं अंततः यह काम करने में सक्षम होने पर गिन रहा हूं। – billc

+0

man2xxl, नीचे चेकआउट आर्मिक्रॉन का जवाब। – billc

उत्तर

5

आपके कार्यान्वयन में कई त्रुटियां हैं। उदाहरण के लिए:

  1. pysrp डिफ़ॉल्ट रूप से SHA1 एल्गोरिदम का उपयोग करता है। इसे SHA256 पर सेट किया जाना चाहिए।
  2. _ng_const लंबाई 3072 बिट्स होना चाहिए और इसे से amazon-cognito-identity-js
  3. कॉपी किया जाना चाहिए pysrp में कोई hkdf समारोह नहीं है।
  4. प्रतिक्रिया में secret_block_b64 होना चाहिए, secret_block_hex नहीं होना चाहिए।
  5. गलत टाइमस्टैम्प प्रारूप। %H:%m:%S का अर्थ है "घंटा: महीना: दूसरा" और +0000UTC द्वारा प्रतिस्थापित किया जाना चाहिए।

क्या किसी ने यह काम किया है?

हां। यह warrant.aws_srp मॉड्यूल में लागू किया गया है। https://github.com/capless/warrant/blob/develop/warrant/aws_srp.py

from warrant.aws_srp import AWSSRP 


USERNAME='xxx' 
PASSWORD='yyy' 
POOL_ID='us-east-1_zzzzz' 
CLIENT_ID = '12xxxxxxxxxxxxxxxxxxxxxxx' 

aws = AWSSRP(username=USERNAME, password=PASSWORD, pool_id=POOL_ID, 
      client_id=CLIENT_ID) 
tokens = aws.authenticate_user() 
id_token = tokens['AuthenticationResult']['IdToken'] 
refresh_token = tokens['AuthenticationResult']['RefreshToken'] 
access_token = tokens['AuthenticationResult']['AccessToken'] 
token_type = tokens['AuthenticationResult']['TokenType'] 

ध्यान दें, कि aws_srp मॉड्यूल master शाखा में अभी तक का विलय नहीं किया गया था।

authenticate_user विधि केवल PASSWORD_VERIFIER चुनौती का समर्थन करता है। यदि आप अन्य चुनौतियों का जवाब देना चाहते हैं, तो बस authenticate_user और boto3 दस्तावेज़ीकरण देखें।

+0

धन्यवाद armicron! – billc

2

दुर्भाग्य से यह एक कठिन समस्या है जब से तुम संगणना के संबंध में सेवा से किसी भी संकेत नहीं मिलता है (यह मुख्य रूप से अधिकृत नहीं कहते हैं के रूप में आप का उल्लेख)।

हम डेवलपर अनुभव में सुधार करने पर काम कर रहे हैं जब उपयोगकर्ता एसआरपी को अपनी भाषाओं में लागू करने की कोशिश कर रहे हैं जहां हमारे पास एसडीके नहीं है। इसके अलावा, हम और एसडीके जोड़ने की कोशिश कर रहे हैं।

जैसा लगता है उतना चुनौतीपूर्ण है, मैं जावास्क्रिप्ट या एंड्रॉइड एसडीके लेना चाहता हूं, इनपुट (एसआरपी_ए, एसआरपीबी, टाइमस्टैम्प) को ठीक करें और यह सुनिश्चित करने के लिए कार्यान्वयन में विभिन्न बिंदुओं पर console.log स्टेटमेंट जोड़ें। गणना समान हैं। फिर आप इन कार्यान्वयन को अपने कार्यान्वयन में चलाएंगे और सुनिश्चित करेंगे कि आप वही प्राप्त कर रहे हैं। जैसा कि आपने सुझाव दिया है, पासवर्ड दावा हस्ताक्षर को सेवा में आधार 64 एन्कोडेड स्ट्रिंग के रूप में पारित करने की आवश्यकता है ताकि यह एक समस्या हो।

बिगइंटर लाइब्रेरी मतभेदों से संबंधित कुछ मुद्दों से संबंधित था (जिस तरह से वे बाइट पैडिंग करते हैं और ऋणात्मक संख्या को बाइट एरे और विपरीत रूप से बदलते हैं)।

+0

धन्यवाद Ionut। मैं उम्मीद कर रहा था कि कोई यह देखेगा कि मुझे कुछ कदम स्पष्ट रूप से गलत मिला है, और मैं आपके द्वारा प्रस्तावित दर्दनाक प्रक्रिया से बच सकता हूं, लेकिन मुझे लगता है कि मैं अटक गया हूं। PASSWORD_CLAIM_SIGNATURE पर टिप के लिए धन्यवाद। मुझे लगता है कि आप का मतलब है कि बेस 64 एन्कोड * कच्चे बाइट्स * एचएमएसी ऑपरेशन से वापस आ गया है, है ना? (और कहें, उन बाइट्स के * हेक्सस्ट्रिंग * का बेस 64?) – billc

+1

हां यही मेरा मतलब है, बेस 64 एचएमएसी ऑपरेशन से लौटे कच्चे बाइट को एन्कोड करता है। –