0

I need the public key certificate that Amazon cognito uses so my web app can verify the cognito JWT. Is there anyway to get the public key certificate or do you have to use the cognito SDK to achieve this?

Fred
  • 1
  • 1
  • 1

3 Answers3

2

Use the get-signing-certificate method from AWS CLI to get the contents of the public x509 certificate for Cognito. Here is a sample command:

aws cognito-idp get-signing-certificate --user-pool-id ca-central-1_xxxxxxxxx

You will get a single line with the base64-encoded certificate. Surround that with the standard markers of -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----. The end result will look like this:

-----BEGIN CERTIFICATE-----
MIICdzCCAeCgAwIBAgIGANc+Ha2wMA0GCSqGSIb3DQEBBQUAMFMxCzAJBgNVBAYT
AlVTMRMwEQYDVQQKEwpBbWF6b24uY29tMQwwCgYDVQQLEwNBV1MxITAfBgNVBAMT
GEFXUyBMaW1pdGVkLUFzc3VyYW5jZSBDQTAeFw0wOTAyMDQxNzE5MjdaFw0xMDAy
MDQxNzE5MjdaMFIxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpBbWF6b24uY29tMRcw
FQYDVQQLEw5BV1MtRGV2ZWxvcGVyczEVMBMGA1UEAxMMNTdxNDl0c3ZwYjRtMIGf
MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpB/vsOwmT/O0td1RqzKjttSBaPjbr
dqwNe9BrOyB08fw2+Ch5oonZYXfGUrT6mkYXH5fQot9HvASrzAKHO596FdJA6DmL
ywdWe1Oggk7zFSXO1Xv+3vPrJtaYxYo3eRIp7w80PMkiOv6M0XK8ubcTouODeJbf
suDqcLnLDxwsvwIDAQABo1cwVTAOBgNVHQ8BAf8EBAMCBaAwFgYDVR0lAQH/BAww
CgYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQULGNaBphBumaKbDRK
CAi0mH8B3mowDQYJKoZIhvcNAQEFBQADgYEAuKxhkXaCLGcqDuweKtO/AEw9ZePH
wr0XqsaIK2HZboqruebXEGsojK4Ks0WzwgrEynuHJwTn760xe39rSqXWIOGrOBaX
wFpWHVjTFMKk+tSDG1lssLHyYWWdFFU4AnejRGORJYNaRHgVTKjHphc5jEhHm0BX
AEaHzTpmEXAMPLE=
-----END CERTIFICATE-----
Liz Av
  • 2,864
  • 1
  • 25
  • 35
1

There is no certificate chain on a Cognito JWK. The public JWK for your Cognito can be found here:

https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json

You can decode the JWK into a PEM Public Key format using a library such as https://www.npmjs.com/package/jwk-to-pem

var jwkToPem = require('jwk-to-pem');

var jwk = JWK_FROM_URL,
    pem = jwkToPem(jwk);

Or you could do the complete verification using something like https://github.com/cisco/node-jose

jose.JWK.asKey(keys[key_index])
  .then(result => jose.JWS.createVerify(result).verify)
  .then(result => JSON.parse(result.payload))

There's a detailed guide to decoding Cognito JWT here https://aws.amazon.com/premiumsupport/knowledge-center/decode-verify-cognito-json-token/, with an sample of using jose on Cognito JWT's here: https://github.com/awslabs/aws-support-tools/blob/master/Cognito/decode-verify-jwt/decode-verify-jwt.js

thomasmichaelwallace
  • 7,926
  • 1
  • 27
  • 33
  • But you can't get the certificate from the site, it just gives you the JWK with the modulus and exponent. I would like the certificate in this form: -----BEGIN CERTIFICATE----- ...... -----END CERTIFICATE-----. Can't find a solution for this on the AWS support guides. – Fred Oct 15 '18 at 14:23
  • I've fleshed out my example a bit, there's no certificate, only a public key, which can be decoded into PEM format (you can test it yourself online here: https://8gwifi.org/jwkconvertfunctions.jsp). See https://security.stackexchange.com/questions/54257/public-keys-without-the-certificates for a discussion as to why AWS might not be using certificates – thomasmichaelwallace Oct 15 '18 at 15:03
1

There is no direct option available but you can do a workaround in openSSL,

  1. Generate a private key and generate a Certificate signing request(CSR) using the available private key. Both can be done in a single line
openssl req -new -newkey rsa:2048 -nodes -keyout PrivateKey_FileName.key -out CSR_FileName.csr
  1. Save the PublicKey from cognito in .pem format. You can convert from jwk to .pem using the online tool https://8gwifi.org/jwkconvertfunctions.jsp.

  2. Self sign the CSR using the generated private key and force the CA to include your custom Public key saved in .pem format to create a certificate replacing whatever public key available when you have generated your CSR request, using the following command.

openssl x509 -req -days 1200 -in CSR_FileName.csr -force_pubkey cognito_publicKeyFileName.pem -signkey PrivateKey_FileName.key -out export_certificate_FileName.crt
  1. Boom..you have created your x509 certificate with the public key from cognito
Vimal Roy
  • 11
  • 1