Aws-sdk-php: Need method to generate SRP_A for authflow USER_SRP_AUTH for InitiateAuth.

Created on 6 Mar 2020  路  33Comments  路  Source: aws/aws-sdk-php

Is this related to a problem?

I want to use USER_SRP_AUTH for InitiateAuth in my application to log the user's device info into Cognito. But I need to pass "SRP_A" as AuthParameters in the request. And we don't have any method in SDK to generate "SRP_A" in the current SDK.

Feature description

It is better if we have the method to generate "SRP_A" in SDK so we can generate it easily.

feature-request

Most helpful comment

Just in case if you guys still need it. I converted Capless Warrant Python code to PHP.

https://gist.github.com/jenky/a4465f73adf90206b3e98c3d36a3be4f

It supports only USER_SRP_AUTH flow, feel free to edit or make any changes you deem necessary.

All 33 comments

Any response on this?

@vivekpipaliya Do you know how the SRP_A value can be generated by yourself?

@sdrenth No, I don't know that. Let me know if you know that I am still finding the solution for it.

@vivekpipaliya I'm not able yet to connect using initiateAuth, but I believe that might have a different cause. I keep receiving this error:

Error retrieving credentials from the instance profile metadata service. (cURL error 7: (see https://curl.haxx.se/libcurl/c/libcurl-errors.html))

I believe this might work, but due to the error above I'm not sure if this works or not:

SRP flow scheme:
https://code.falk-m.de/srp/

Source code:
https://github.com/falkmueller/srp/

Please let me know if that works for you.

Thanks for that... I will try to generate SRP_A using this library and let you know if it works.

@vivekpipaliya The initiateAuth method is working for me now:

$client = new CognitoIdentityProviderClient([
    'version' => 'latest',
    'region'  => 'eu-west-1',
    'credentials' => false,
]);

$srp = new Srp();
$a = $srp->getRandomSeed();
$A = $srp->generateA($a);

$result = $client->initiateAuth([
    'UserPoolId'     => 'USER_POOL_ID',
    'ClientId'       => 'CLIENT_ID',
    'AuthFlow'       => 'USER_SRP_AUTH',
    'AuthParameters' => [
        'USERNAME' => 'USERNAME',
        'SRP_A'    => $A
    ]
]);

Currently I'm struggling to find out how I should implement the respondToAuthChallenge. I'll let you know if I've found out how that should be done.

What is the "ChallengeName" you are receiving in the response of initiateAuth method?

@vivekpipaliya PASSWORD_VERIFIER is the challenge name I received and believe that that is correct.

I'm currently stuck at the PASSWORD_CLAIM_SIGNATURE parameter in the respondToAuthChallenge.

What did you pass for TIMESTAMP?

I am on the same stage and getting this error.
Unable to verify secret hash for client xxxxxxxx

@sdrenth I am getting Unable to verify secret hash for client xxxxxxxx on respondToAuthChallenge request.
What problem are you facing in respondToAuthChallenge request?

@vivekpipaliya This is what I used for the date:
$date = date('D M d H:i:s T Y');

I'm using the code below for the respondToAuthChallenge method:

$date = date('D M d H:i:s T Y');

$srp = new Srp();
$a = $srp->getRandomSeed();
$A = $srp->generateA($a);

$challengeParameters = $result->get('ChallengeParameters');

$s = $srp->getRandomSeed();
$x = $srp->generateX($s, 'MY_USERNAME', 'MY_PASSWORD');
$S = $srp->generateS_Client($A, $challengeParameters['SRP_B'], $a, $x);
$K = $srp->generateK($S);

$response = $client->respondToAuthChallenge([
    'ChallengeName'      => 'PASSWORD_VERIFIER',
    'ClientId'           => 'CLIENT_ID',
    'ChallengeResponses' => [
        'TIMESTAMP'                   => $date,
        'USERNAME'                    => $challengeParameters['USER_ID_FOR_SRP'],
        'PASSWORD_CLAIM_SECRET_BLOCK' => $challengeParameters['SECRET_BLOCK'],
        'PASSWORD_CLAIM_SIGNATURE'    => hash_hmac('sha256', $K, $challengeParameters['SALT'])
    ]
]);

This gives me this error:

Bad Request` response:
{"__type":"NotAuthorizedException","message":"Incorrect username or password."}

Most like this error is caused by an incorrect PASSWORD_CLAIM_SIGNATURE. Since I haven't really found out what this key should contain as a value and just tried some things based on documentation and java code I've found.

@sdrenth Did you find any solution to generate PASSWORD_CLAIM_SIGNATURE? We are both on the same page.

@vivekpipaliya Unfortunately not yet

@vivekpipaliya Thank you for creating the thread on Amazon Forums, I was just going to do that when I noticed your thread. If anyone else is interested in this, the thread is found here:
https://forums.aws.amazon.com/thread.jspa?threadID=321244&tstart=0

@sdrenth I am trying to use USER_SRP_AUTH to use remember devices functionality.

https://aws.amazon.com/premiumsupport/knowledge-center/cognito-user-pool-remembered-devices/

Is there any reason you are using USER_SRP_AUTH? If you just want to login user then you can use adminInitiateAuth with ADMIN_NO_SRP_AUTH

@vivekpipaliya It's a requirement from the client that I implement the initiateAuth method, according to them the adminInitiateAuth method is not an option. Also they've implemented it for Java/Python before and are helping me as well.

I'm unable to find any documentation about how to generate the PASSWORD_CLAIM_SIGNATURE.

@sdrenth You can move to the bottom of the page from below link and check this thing if that helps you to generate PASSWORD_CLAIM_SIGNATURE.

https://aws.amazon.com/premiumsupport/knowledge-center/cognito-user-pool-remembered-devices/

image

Actually I have also tried different methods to generate PASSWORD_CLAIM_SIGNATURE but was not able to generate it correctly. That's why I posted this thing on both AWS Forum and StackOverflow

Here is the link for StackOverflow question

https://stackoverflow.com/questions/61495005/couldnt-generate-correct-password-claim-signature-in-php-for-cognito

@vivekpipaliya I think it would need to be something like this (untested):

SHA256_HMAC(K_USER, USERPOOL_ID (without region) + USERID_FOR_SRP + base64 decoded PASSWORD_CLAIM_SECRET_BLOCK + TIMESTAMP), base64-encoded

Hi, @sdrenth Did you found any solution?

@vivekpipaliya I haven't had any time yet to test the value of my previous comment.

I found the Capless Warrant Python code very helpful in understanding the whole process.

https://github.com/capless/warrant/blob/ff2e4793d8479e770f2461ef7cbc0c15ee784395/warrant/aws_srp.py#L93

@sdrenth Any updates here? I'm running into the exact same issue. Just receiving "Incorrect username or password." Also tried several different generated signatures without success.

@chuelsmann I ended up using a workaround with calling a JAR file that was provided to me by a third-party, so I cannot be of help here. When calling the JAR file I had some issues with the password encoding, by using a password with only ! and no weird characters helped me getting it to work. So maybe that is something for you to consider as well. Hopefully, you'll be able to get it to work.

I've implemented the PASSWORD_CLAIM_SIGNATUR calculation on PHP and compare it with CognitoUser.js of my Amplify application.

The PHP application generates the same PASSWORD_CLAIM_SIGNATUR as the CognitoUser.js library for the same input properties.

But anyway in the PHP I receive "Incorrect username or password." response while JS application passes authentication successfully.

Is there something wrong with the PHP SDK? Is it possible to receive any details about what is going wrong from AWS?

@SANiMirrorOfLight I've had the same issue. I tested on my Windows machine where I was able to login using the same credentials and on my Macbook I was unable to, this was due to:

When calling the JAR file I had some issues with the password encoding, by using a password with only ! and no weird characters helped me getting it to work. So maybe that is something for you to consider as well. Hopefully, you'll be able to get it to work.

@sdrenth I've tried using a password without "!" but anyway Cognito returned "Incorrect username or password.". Also, I don't think that there is an encoding issue in my case because it seems like my PHP program code generates the same PASSWORD_CLAIM_SIGNATUR hash as CognitoUser.js library.

@SANiMirrorOfLight I've had the same issue. I tested on my Windows machine where I was able to login using the same credentials and on my Macbook I was unable to, this was due to:

@SANiMirrorOfLight I removed all weird characters from my password except "!", because at least 1 character was required, so I ended up with a password with looks something like:
1234abcdefgh!

But I can't help you any further unfortunately because I was unable to find out how to generate it using PHP (as in, it would take way to much time). So I ended up calling a JAR file in PHP which handled the AWS authentication part for me using JAVA. Maybe something like that would work for you as well.

So I ended up with something like this, where I pass the authentication details to the JAR file as parameters:
exec('/my_jar_file.jar param1 param2', $response);

I converted the Python version linked above to Ruby. Here is the gist in case anyone finds it useful.

https://gist.github.com/jviney/5fd0fab96cd70d5d46853f052be4744c

This could be translated to PHP as well quite easily.

Just in case if you guys still need it. I converted Capless Warrant Python code to PHP.

https://gist.github.com/jenky/a4465f73adf90206b3e98c3d36a3be4f

It supports only USER_SRP_AUTH flow, feel free to edit or make any changes you deem necessary.

Just in case if you guys still need it. I converted Capless Warrant Python code to PHP.

https://gist.github.com/jenky/a4465f73adf90206b3e98c3d36a3be4f

It supports only USER_SRP_AUTH flow, feel free to edit or make any changes you deem necessary.

It is a good idea to use the BigInteger here, I have used the DC Math function in my lib. But anyway both variants, your and my, do not work in my case because I have negative$intValue2 and bcpowmod cannot work correctly with a negative value. In the case of using the BigInteger library, I received positive $intValue2 but the s value is calculated with the wrong value in this case.

This way, in my lib I use the python script for calculating the correct s value.

Maybe I am missing anything? Have anyone tested this with AWS SRP authorization?

It worked for me, maybe you could try to debug the calculated a, A, s, u values from both python and php to see the differences.

Was this page helpful?
0 / 5 - 0 ratings