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?
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-----
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
There is no direct option available but you can do a workaround in openSSL,
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
Save the PublicKey from cognito in .pem format. You can convert from jwk to .pem using the online tool https://8gwifi.org/jwkconvertfunctions.jsp.
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
Boom..you have created your x509 certificate with the public key from cognito
Related
I am trying to enable mTLS for Amazon API Gateway for my endpoint, and I have my existing public key (PKI) for my domain (.crt & .key)..While using to upload my existing root CA public key in S3 bucket, I am getting some error like "API Gateway couldn’t build a unique path from the given certificate to a root certificate". I am following the setup using this link,
Ref : https://aws.amazon.com/blogs/compute/introducing-mutual-tls-authentication-for-amazon-api-gateway/
Note : I am not using the openssl to generate the RootCA.pem & RootCA.key.
Step 1: (SKIP)
Create the private certificate authority (CA) private and public keys: openssl genrsa -out RootCA.key 4096 openssl req -new -x509 -days 3650 -key RootCA.key -out RootCA.pem
Step 2:
Create client certificate private key and certificate signing request (CSR): openssl genrsa -out my_client.key 2048 openssl req -new -key my_client.key -out my_client.csr
Step 3:
Sign the newly created client cert by using your certificate authority you previously created: openssl x509 -req -in my_client.csr -CA RootCA.pem -CAkey RootCA.key -set_serial 01 -out my_client.pem -days 3650 -sha256
Step 4:
I have a minimum of five files in my directory RootCA.key (root CA private key) RootCA.pem (root CA public key) my_client.csr (client certificate signing request) my_client.key (client certificate private key) my_client.pem (client certificate public key)
Step 5:
Prepare a PEM-encoded trust store file for all certificate authority public keys you want to use with mutual TLS: cp RootCA.pem truststore.pem
Step 6:
Upload the trust store file to an Amazon S3 bucket in the same AWS account as our API Gateway API. aws s3 mb s3://your-name-ca-truststore --region us-east-1 #creates a new S3 bucket – skip if using existing bucket aws s3api put-bucket-versioning --bucket your-name-ca-truststore --versioning-configuration Status=Enabled #enables versioning on S3 bucket aws s3 cp truststore.pem s3://your-name-ca-truststore/truststore.pem #uploads object to S3 bucket
Step 7:
Enabling mutual TLS on a custom domain name I have in AWS API gateway console, While I upload my existing root CA public key in S3 bucket, I am getting some error like
Error : "API Gateway couldn’t build a unique path from the given certificate to a root certificate".
Error : "There is an invalid certificate in your truststore bundle Mutual TLS is still enabled, but some clients might not be able to access your API. Upload a new truststore bundle version to S3, and then update your domain name to use the new version."
I'm trying to encrypt TLS traffic in transit between EMR nodes. The example on the AWS website uses a self-signed certificate.
Because this is all within my private network, I have generated a root CA certificate with a private key that is tightly secured. I then have a derived certificate which can perform key encipherment", digital signature, and server auth.
Let's call the root CA certificate A, and the derived certificate B.
EMR says that I need to upload a zipfile to s3 containing 2 required files and one optional file:
privateKey.pem is required,
certificateChain.pem is required
and trustedCertificates.pem is optional
For privateKey.pem, I assume I can just use the private key associated with certificate B.
For certificateChain.pem, do I need the contents of the certificate B concatenated with certificate A or do I just need the contents of certificate A?
For trustedCertificates.pem do I need the contents of certificate A or of certificate B?
If you follow this AWS script as per the documentation you will find that trustedCertificates.pem and certificateChain.pem are the same file (via a file copy).
openssl req -x509 -newkey rsa:2048 -keyout privateKey.pem -out certificateChain.pem -days 365 -nodes -subj '/C=US/S=Washington/L=Seattle/O=MyOrg/OU=MyDept/CN=*.ec2.internal'
cp certificateChain.pem trustedCertificates.pem
zip -r -X certs.zip privateKey.pem certificateChain.pem trustedCertificates.pem
EMR Create Certificate Script
You are complicating things by creating a root certificate, which is not necessary. Follow the AWS documentation on setting up TLS on EMR:
Secure Amazon EMR with Encryption
The zip file that you upload to S3 contains three files, privateKey.pem, certificateChain.pem and trustedCertificates.pem. Two of which are the same file with different names.
[EDIT after a very long comment thread on certificates]
When you create a self signed root certificate, all certificates that it signs are also self signed. A certificate is verified by verifying each certificate up the chain to the root. If the root certificate is untrusted, then all certificates are untrusted.
AWS offers a certificate management service where you can be your own CA. However, this is very expensive. If you are a large company, a bank or financial institution, etc. then this AWS service is very useful.
For Amazon EMR, using a single self signed certificate is OK. The reasoning is that you are in full control over the systems that are using the certificate. You would not want to use a self signed certificate if any part of the system is providing public access.
One item that confused the OP is the difference between a trusted certificate and the certificate chain. In his example, since their is only the root certificate and not intermediary certificates, the trusted and chain are the same item. Only if he had created another signing certificate that was used to sign the last certificate would the certificate chain be different (there would be the root certificate and the signing certificate).
I am trying to implement Allow only trusted devices feature on AWS Workspaces with simple AD.
Can someone please guide me how to generate self-signed root & client certificate with following features.
Certificates must be Base64-encoded certificate files in CRT, CERT, or PEM format.
Certificates must include a Common Name.
The maximum length of certificate chain supported is 4.
Amazon WorkSpaces does not currently support device revocation mechanisms, such as certificate revocation lists (CRL) or Online Certificate Status Protocol (OCSP), for client certificates.
Use a strong encryption algorithm. We recommend SHA256 with RSA, SHA256 with CEDSA, SHA381 with CEDSA, or SHA512 with CEDSA.
You need to create CA first:
SERVER_NAME=fred
DOMAIN_NAME=domain.local
export $SERVER_NAME $DOMAIN_NAME
openssl genrsa -out CA_$SERVER_NAME.$DOMAIN_NAME.key 2048
openssl req -x509 -new -nodes -key CA_$SERVER_NAME.$DOMAIN_NAME.key -sha256 -days 1024 -out CA_$SERVER_NAME.$DOMAIN_NAME.pem -subj "/C=GB/ST=MyCounty/L=MyTown/O=MyOrganisation/OU=MyOrganisationUnit/CN=$SERVER_NAME.$DOMAIN_NAME
Then you can create certificates signed from the CA you just created.
openssl genrsa -out $SERVER_NAME.$DOMAIN_NAME.key 2048
openssl req -new -key $SERVER_NAME.$DOMAIN_NAME.key -out $SERVER_NAME.$DOMAIN_NAME.csr -subj "/C=GB/ST=MyCounty/L=MyTown/O=MyOrganisation/OU=MyOrganisationUnit/CN=$SERVER_NAME.$DOMAIN_NAME.client"
openssl x509 -req -in $SERVER_NAME.$DOMAIN_NAME.csr -CA CA_$SERVER_NAME.$DOMAIN_NAME.pem -CAkey CA_$SERVER_NAME.$DOMAIN_NAME.key -CAcreateserial -out $SERVER_NAME.$DOMAIN_NAME.crt -days 365 -sha256
Now you have a CA and a certificate created, you can test that the certificate is created from the CA by running:
openssl verify -CAfile CA_fred.domain.local.pem fred.domain.local.crt
Thanks #IchingChang, article https://www.brunton-spall.co.uk/post/2020/04/28/Using-AWS-Workspaces/ is really helpful.
For future readers, if you still struggling with this problem, also try with bruntonspall's github link: https://github.com/bruntonspall/AWSWorkspacesCA
The following step is create all keys and certificates in same machine (CA machine), for prod use case, you should create client public and private key in client machine:
(only do this step if you want to renew or did not create and upload your CA public key before) run ./CA/gen_CA.sh, which will generate CA's private and public key, copy the public key (.pem file) and upload it onto AWS Workspaces's Directory Service's Access Control Options (https://docs.aws.amazon.com/workspaces/latest/adminguide/trusted-devices.html#configure-restriction).
run ./client/gen_client.sh, which will generate client private and public key and corresponding CA sign certificate.
copy pfx (or say p12) certificate file to your windows laptop, click install, select current user and personal store.
Now you should be able to login with your workspaces client (suppose you already setup AWS Workspaces side correctly with other settings).
I am generating JWT token from WSOAM which is then passed as a header to API. I have my API created in nodejs and I am using jsonwebtoken plugin to verify and decode the JWT.
I am unable to find RSA Public key of Wso2carbon to verify/decode the token.
Please help me as how to generate the RSA Public key or where should I find this key ?
All WSO2 products use the default public/private key pairs installed into wso2carbon.jks keystore file found in <WSO2_AM>/repository/resources/security directory. It's advised to use your own keystore instead of this default keystore shipped with all WSO2 products.
It is recommended to replace this default keystore with a new keystore
that has self-signed or CA signed certificates when the products are
deployed in production environments. This is because wso2carbon.jks is
available with open source WSO2 products, which means anyone can have
access to the private key of the default keystore.
If you are going to use the default private/public keys, use the following command to extract the key.
keytool -export -keystore <WSO2_AM>/repository/resources/security/wso2carbon.jks -alias wso2carbon -file Example.cer
I get this error while trying to upload my certificates:
A client error (KeyPairMismatch) occurred when calling the
UploadServerCertificate operation: The private key did not match
the public key provided. Please verify the key material and try
again.
I have followed all of the instructions on how to create and upload server certificates in the link here:
http://docs.aws.amazon.com/IAM/latest/UserGuide/InstallCert.html
I have also received the following certificates through email:
as PKCS#7 Base64 encoded
as PKCS#7 Bin encoded
as X509, Base64 encoded
as X509 Certificate only, Base64 encoded
as X509 Intermediates/root only, Base64 encoded
as X509 Intermediates/root only Reverse, Base64 encoded
and I have laid out the upload code like this:
aws iam upload-server-certificate --server-certificate-name my_cert_edu
--certificate-body file://my_cert_edu.pem --private-key file://MYtesting.pem
--certificate-chain file://my_cert_edu_interm.pem