AWS Cognito DeviceConfirm sending InvalidParameterException : Found negative value for salt or password verifier.

0

Hello,

I'm a bit stuck with one of my code project. I'm so close to succeed and still blocked on confirming the device to avoid MFA challenge each time I log in the website.

Setup

I have a user pool which has one user. The user pool has device tracking access. I have a **react **website where I implemented end to end login in Typescript. Registration is done by the AWS console directly. I currently ended the flow with all the tokens, device key and device group key.

I'm calling device confirm command with the Salt and Password Verifier but I have the following error:

{"__type":"InvalidParameterException","message":"Found negative value for salt or password verifier."}

Here's the result of the authentication:

{
    ...,
    "AuthenticationResult": {
        "AccessToken": "eyJraWQ...",
        "ExpiresIn": 3600,
        "IdToken": "eyJraWQi...",
        "NewDeviceMetadata": {
            "DeviceGroupKey": "-7Qw...",
            "DeviceKey": "eu-west-1_4f50..."
        },
        "RefreshToken": "eyJjdHkiO...",
        "TokenType": "Bearer"
    },
    "ChallengeParameters": {}
}

Here's my input for the confirm device command:

{
    "AccessToken": "eyJraWQiOi...",
    "DeviceKey": "eu-west-1_4f50ca99-45e6-4ac2-8284-82ccaf210a24",
    "DeviceName": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
    "DeviceSecretVerifierConfig": {
        "PasswordVerifier": "00f27101...",
        "Salt": "2337001e79ef1ca301803ee7fd38410c"
    }
}

I've found several issues and fixed it along the development:

  1. Device tracking requires SRP Auth Flow to properly work
  2. Device has to be password verified
  3. I'm also not very sure about what to send as parameters. I found examples with DeviceGroupKey and username and other with DeviceGroupKey and DeviceKey.

I've tried different solutions but at the end I'm still having that result.

  1. Using Amplify is not an option as my point is to prove we can have a simple solution on integrating cognito. I tried so far: with a compatible library for crypto algorithm in the browser written in TS, pbkdf2
  2. by copying file by file the code from amplify js using the generateHashDevice function

So, my asks are:

  1. Can some AWS expert can explain me what is missing / false and unblock me?
  2. Maybe I did not do the right thing but can you point out a good example in typescript (here's one in python) generating both Salt and PasswordVerifier? I searched on internet but found partial answers and still no real information about. And extra complexity, it should not use Crypto or Buffer as webpack 5 decided to stop backward compatibility with polyfills.
  3. The full developer experience is long and difficult, all examples are not up to date or linked to the amazon cognito provider js which has been integrated in AWS amplify. So basically, we have no example on how to implement the end to end process with device confirmation. AWS documentation for Confirm Device | AWS Javascript example onf confirming device

I'm apparently not the only one, other developers experience the same problem.

Many many many thanks on this one!

W

  • I am also having same problem, even I was not able to perform confirmDevice with react/typescript codes.

    If you can help me for how did you able to generate or grab passwordVerifer value? I got stuck with this formula here PasswordVerifier = g( SHA256_HASH(salt + FULL_PASSWORD) ) (mod N)

Wascou
asked 6 months ago211 views
1 Answer
0
Accepted Answer

Answering my own post after a discussion with a Solutions Architect from AWS.

AWS told me in substance:

  1. Building its own SRP lib is non sense because it won't be as tested as AWS or Mozilla did (other example of SRP implementation)
  2. Not relying on what exists already is non sense also: Amplify lib has already everything to do the job regarding talking to Cognito.
  3. Amplify team is slowly building a TS version but it takes time as the code is really granular and the Auth lib is tangled with other functions in the package which makes it not autonomous.
  4. By doing that you have to rebuild the user experience and the chain of screens / forms the user has to complete to authenticate.

What I did;

  1. I was very reluctant to use amplify but I strictly imported only few bits of it to do the job. The right flavor compatible with typescript is the package named "aws-amplify". In this one, the Auth function handles all the auth flows and generates SRP for us. You might some other repos with JS, don't use those, it's not up to date.
  2. I rebuild the ux with different screens, one for the signin (email, password), one for the mfa challenge (mfa code sent by email or SMS). You have to maintain a context has you have to pipe value from one form to the cirresponding Auth calls.
  3. I developped 4 functions. Three of those need a context: one to process the signin (Auth.signIn(username, password)), one to handle the mfa (Auth.confirmSignIn(user, mfa, "SMS_MFA")), and finally to know if the current user is logged in or not (Auth.currentAuthenticatedUser()). If your device is trusted then the challenge is over after the step 1, so you can reload your page directly. The last one is the logout (Auth.signOut()).
  4. I'm using React Router Dom 6.2 but I guess it's the same of other React Frameworks, I developped a small wrapper around my App object which is handling the logged in state of the application. If the user is not logged in, the login form shows up, if the user is logged in then we send back the children of the wrapper (meaning the app) (return props.children)

package.json

...
 "aws-amplify": "^5.3.12",
...

cognito.ts

import { Amplify, Auth } from "aws-amplify"

What I got:

  1. a clear login interface, with high performance (really)
  2. a control on the user flow, login and logout, no password forgotten
  3. the mfa challenge implemented (watch out for the cost during the test phases if you use SMS)

I guess the last step is to wait the Amplify team to clearly untangle their Auth function without the full package of aws-amplify to have something clean. At the moment I use also the axios lib shipped with Amplify to proxy my request toward API Gateway, so that's fine, a good trade off.

Good luck with all this.

W

Wascou
answered 4 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions