where can I find the secret key for the JWT from cognito

16,147

Solution 1

To correct the other answer: RS256 is an asymmetric algorithm and requires a public and a private key. Also see RS256 vs HS256: What's the difference? and https://en.wikipedia.org/wiki/RSA_(cryptosystem).

What is correct is that for verifying the JWT you do not need the private key that was used to sign it, only the public key made available by AWS under https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json.

Solution 2

Just want to summarize this topic with the snippet of code:

const jwkToPem = require('jwk-to-pem');
const requestify = require('requestify');

/**
 * Get cognito's secret key
 * @param {String} region
 * @param {String} userPoolId
 * @returns {Promise}
 */
function getPem(region, userPoolId) {
  const jwkUrl = `https://cognito-idp.${region}.amazonaws.com/${userPoolId}/.well-known/jwks.json`;

  return requestify.request(jwkUrl, { method: 'get', dataType: 'json'})
    .then(res => res.getBody()['keys'].shift())
    .then(jwk => jwkToPem(jwk))
  ;
}

Solution 3

AWS uses RS256 algorithm which does not require secret but public key to decode.

Here you will find JWKS of your pool: https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json (See http://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html#amazon-cognito-identity-user-pools-using-id-and-access-tokens-in-web-api)

And here is described process of transforming JWK to the public key: https://mobile.awsblog.com/post/Tx3JK25U7Z9EUIU/Integrating-Amazon-Cognito-User-Pools-with-API-Gateway (under section "Understanding the code").

Share:
16,147

Related videos on Youtube

leo c
Author by

leo c

Updated on July 20, 2022

Comments

  • leo c
    leo c almost 2 years

    I am trying out the log in function for the Cognito User Pool for my Web App. I was able to obtain the Token but I am not sure where to find the secret to decode it. I've read in one of the post that the secret is the secret Id for the App in the User Pool. However, for Javascript SDK, the secret id is blank. Does this mean my secret should also be blank? I tried this but I got a message that says "Error: PEM_read_bio_PUBKEY failed".

  • B M
    B M over 7 years
    sorry but this is plain wrong - RS256 is an asymmetric algorithm and requires a public and a private key. What would be correct is that for verifying the JWT you do not need the private key that was used to sign it.
  • Jefree Sujit
    Jefree Sujit almost 7 years
    I got an array of Json from there, which attribute contains the public key for the token? trying out with the value in "n" attribute throws signature is invalid
  • javierfdezg
    javierfdezg over 6 years
    Agree with B M comment.
  • JakubM
    JakubM over 6 years
    I was answering the question which was "where to find the secret to decode it" (and not about general functioning of the RS256) so I consider my answer right.
  • ecoe
    ecoe almost 6 years
    @JefreeSujit The JWT will contain a "kid" (key ID), which decides the JWK to use from the cognito-idp request shown above. You then need the JWK's n (modulus) and e (public exponent) to convert to a "pem" formatted RSA public key. Here is a one-liner in scala (using java libraries) for the conversion (n & e are strings): Base64.getEncoder.encodeToString(KeyFactory.getInstance("RSA‌​").generatePublic(ne‌​w RSAPublicKeySpec(new BigInteger(1, Base64.getUrlDecoder.decode(n)), new BigInteger(1, Base64.getUrlDecoder.decode(e)))).getEncoded)
  • Nikitas
    Nikitas over 5 years
    Your answer is enormously misleading
  • Swapnil Mhaske
    Swapnil Mhaske over 3 years
    Good summary. But we will have to find the matching key from the keys array using kid. and then pass to jwkTOPem()
  • D.Dimitrioglo
    D.Dimitrioglo over 3 years
    feel free to improve this function ;)