validating a JWT generated by WSO2 APIM 1.9.0: what's the public key? - wso2

I'm trying to do something that seemed simple but ends up being difficult because I lack the expertise.
I have an APIM deployed with no customisation security-wise (don't worry, it's not production!). So it's only got carbon.jks.
I authenticate users in an application with SAML2 against an IDS, then use the APIM with an app secret for a user token generated from the SAML2 token. I get from the APIM an OAuth token which I use to call APIs in the APIM. (note that I managed to resolve this thanks to another post here some time ago :-) )
The backend that implements the APIs receives a JWT as a result, with header, user information and app information, and a signature.
For my first tests I write my own "hello world" backend, that logs the JWT.
I use http://jwt.io which manages to read my JWT without any problem. But it tells me the signature is invalid.
To make the signature valid I would need a valid public key.
I don't know where to find that key.
I have run the command line described in RSA Public Key of WSO2carbon and generated a .cert file. I have examined the .cert file in portecle (http://portecle.sourceforge.net/) but found nothing of interest, however opening it in Windows gave me a field "public key", which looks like "30 81 89 02 81 81 00 94 a[...]", quite long and obviously hex.
I tried this, and also its base64-encoded representation, in http://jwt.io but no success.
Because I was wondering where my public key is, I have also read:
How to validate a JWT from WSO2 API Manager
(and the referenced link https://asankad.org/2013/12/05/obtaining-certificate-used-to-sign-a-jwt/ )
However the code provided is a bit on its own, with not even a mention of language. I assume it's node.js, but no info about libs or anything.
Here are some more precise questions:
WSO2 APIM offers only SHA256withRSA (which is a flavor of SHA2 IIUC). wso2carbon.jks cert that I found were sha1. So I'm supposing that could not have worked anyway. How can APIM generate SHA256 with SHA1 certificates?
WSO2 APIM offers only SHA256withRSA. http://jwt.io gives the choice between RS256 and HS256, one uses a key, the other a secret (public/private). I'm guessing I need to use RS256? (but again the only keys I have seem to come from SHA1 certs)
has anyone succeeded in what I'm doing? Install WSO2 APIM, generate a JWT and validate the JWT against http://jwt.io, including signature?
If I use a lib such as https://github.com/tymondesigns/jwt-auth to validate the JWT, will it work? I was told that this lib doesn't support SHA256.
in the APIM I'm in a tenancy, called sandbox. If I go to the super-tenancy carbon I see wso2carbon.jks. If I go to my own tenancy's carbon I see sandbox.jks, but it's empty, and on the deployment machine there's no corresponding file. How does that work out, does the tenancy JKS exist only when used, or is it stored in the DB and not filesystem?
how much can I show of my tokens, JWT etc on a public forum? :-) (if it helps to help me, I'm willing to share!)
Thanks for any tips!
(maybe all I need is the default public key, seeing as I'm using the default keystore!)

Answering myself in case anyone has the same issue.
Two things helped me out:
first, to validate in jwt.io, I needed to change the cert encoding by running the following command: openssl x509 -inform der -in somekey.cer -out somekey.pem
then I was using the super-tenant keystore instead of the tenancy keystore. I had looked into this but not found any tenancy keystore on the APIM VM. I had to:
log in as tenant admin in APIM carbon portal
navigate to configure / keystores
there was a keystore for the tenancy (called sandbox1.jks), click on public key
save the downloaded sandbox1.cert and convert it to pem using the above command
The resulting pem worked fine with jwt.io using RS256
Hope this helps others!

Related

Exporting certificates from AWS to Azure Key Vault

I have been following this sample from AWS. I have followed the guide, downloaded the certificates, converted them into .pfx and tested them in a local code similar to the sample. The code works fine and the intended connection can be established. However, when I try to upload the certificate to Azure Key Vault, I get this error:
The specified X.509 certificate content is invalid. Error: one or more x.509 properties are invalid.
I have Googled and tested quite a few different openssl commands, and also tried to upload through PowerShell (just incase), but its always the same error. I am a bit clueless as to why this (as far as I know) official AWS example does not just work, and why I can not just export certificates from one big cloud company to another.
Does anyone have any guesses as to what is going wrong and what properties may be invalid, or how I can find out?
PS: My Azure code is getting all configurations from the Key Vault secrets (connection strings, etc). I figured it could similarly be used to store certificates that my code can retrieve and use, instead of storing the certificate file in the project. Do let me know if I have misunderstood what kind of certificates should be saved in the Key Vault.
Please check if following can be worked around:
Please note that Key Vault requires /accepts only a PEM or PFX file
along with a private key.
If you have a private key stored separately in a different format,
you need to combine the key with the certificate and key should not
be encrypted. Some certificate authorities (CAs) provide certificates
in other formats. Therefore, before you import the certificate, make
sure that it's in either PEM or PFX file format and it uses key
either (RSA) or elliptic-curve cryptography (ECC) encryption. see
creating a certificate with a ca not partnered with key-vault
Some factors to check:
Please check if the Pfx was expired or Pfx password is incorrect or
has an invalid format.
Try Re-importing the cert from a pfx file with the --password
parameter if it is password protected.
Also make sure you have access policies created create,get
,set,delete ,list for user that is trying to create and also for the
application.
And the name of the secret or certificate that you are uploading
must be unique and should not match with any other secret that was
created previously. Content-type must be application/x-pkcs12 for
pfx file.
Also check the similar case from SO reference
References:
Understand X.509 public key certificates | Microsoft Docs /About Azure Key Vault Certificates
"The parameter KeyVault Certificate has an invalid value"- Microsoft
Q&A

WSO2IS 5.3.0 - Federated SAML & Enable Authentication Request Signing

I am trying to set up a federated SAML connection in WSO2IS 5.3.0 with Authentication Request Signing enabled. Per the doc https://is.docs.wso2.com/en/latest/learn/configuring-saml-2.0-web-sso/
"Selecting this checkbox enables you to sign the authentication request. If this is enabled, you must sign the request using the private key of the identity provider."
I do have a certificate that I've shared with the federated IDP. However, I am not sure where I need to add the private key that is being referred to on the WSO2 side. I have added it to the global keystore (in <WSO2IS_HOME>/repository/security/wso2carbon.jks ), but that does not seem to be working.
If there is other documentation I'm not finding, or if I could be pointed to the code that does the signing, that'd be helpful. Thanks in advance
Based on this code DefaultSAML2SSOManager.java I was able to determine the steps I needed to take:
If you require the private key to be associated with just a single tenant (which was my case), it needs to be added to the tenant's keystore. This means that the default tenant keystore needs to be replaced with a keystore with this private key (with the same name based on this code X509CredentialImpl.java ). I followed the steps here to do this http://xacmlinfo.org/2014/11/05/how-to-changing-the-primary-keystore-of-a-tenant-in-carbon-products/
If the private key can be global, the application-authenticator.xml file in <WSO2IS_HOME>/repository/conf/identity needs to be updated to have the "SignAuth2SAMLUsingSuperTenant" attribute be true (I did not need this so I did not test it, so take this with a grain of salt).

How to authenthicate from my application to a SSO of my client

I am developing a web application using EC2 on AWS.
In this application my client is requesting to use his SSO (Single Sign On) so I can verify the user against his Active Directory. My problem is that I can't get to know where to begin with, these are some of my questions:
1) Is this SSO takes place on my code or on my server?
2) Do I have to make different configuration for differents deployment environments (for example aws, azure, digitalocean, etc)?
3) Where do I define, send and parse SAML 2.0 format?
4) Do I have the send a POST request to the server where the SSO is installed? Or how is it managed?
So far I have found this tutorial, but I am still do not know what to do first, so any step by step information will help a lot.
First you need the client (Identity Provider IdP) SAML2 metadata. This will have their SSO endpoint URL and their X509 signing certificate.
Then you send them your SAML2 metadata with your Attribute Consumer Service (ACS) URL and X509 signing certificate.
Sample metadata here. Or you can build it here.
The certificates are normally long lived self signed certificates. They can be self signed as each side has a copy of the other's certificate which they will use to verify the signed request and response.
You construct a SAMLRequest and POST it to their SSO URL. There's an example request here.
They display their login page to the user and the user authenticates at their end.
They gather attributes for the user from their Active Directory and turn them into SAML attributes and put them in a SAMLResponse.
They POST the SAMLResponse to your ACS URL. There's an example response here.
You verify the signature on their SAMLResponse using their X509 certificate from their SAML2 metadata.
You extract the SAML Attributes from their verified SAMLResponse and take appropriate action in your application, e.g. create the user an account, perhaps their email address is one of their attributes.
The above is called the SAML2 Web Browser SSO Profile, explained here.
Depending on your stack, you can use something like:
Shibboleth (middleware, install on your server, it interrupts requests to specific paths requiring Authn against the Identity Provider [ADFS], and returns the user after successful auth setting some attributes telling you info about the user such as username, etc.). Works best if you can compartmentalize secured content into a particular path on the site like /secure.
SimpleSAMLphp (protect PHP resources directly)
Commercial SAML (ComponentSpace, etc. - works well if .Net app)
Basically, find something for your stack. DO NOT TRY TO ROLL YOUR OWN SAML IMPLEMENTATION!

How can I externally verify a JWT token that has been signed with an RSA private key

I have a JWT token from AWS Cognito. The token is obtained via a call to getOpenIdTokenForDeveloperIdentity and I'm using the flow for AWS Cognito Developer Authenticated identity
The token is hashed with SHA512 and signed with Amazons RSA private key for the region/zone I'm using.
How can I externally verify the signature with python?
Answering my own question here in the hope it helps somebody.
In my case I wanted to verify the signature of a JWT token obtained via the AWS Cognito Developer Authenticated identity route. No AWS API Gateway involvement.
Like many posters on various sites I had trouble piecing together exactly the bits I needs to verify the signature of an AWS JWT token externally i.e., server side or via script
I think I figured out out and put a gist to verify an AWS JWT token signature. It'll verify an AWS JWT/JWS token with either pyjwt or PKCS1_v1_5c from Crypto.Signature in PyCrypto
So, yes this was python in my case but it's also doable easily in node (npm install jsonwebtoken jwk-to-pem request).
I attempted to highlight some gotchas in the comments because when I was trying to figure this out I was mostly doing the right thing but there were some nuances like python dict ordering, or lack there of, and json representation.
I've also noticed some questions around about doing the validation using the signers Certificate. I'll amend my gist to show this also.
Hopefully it may help somebody somewhere.

Error changing admin password wso2am-2.0.0 new install

I've changed the wso2carbon.jks keystore to my own store and my CA signed cert is working fine via a remote browser for https. However when I try to change the admin password via the carbon management console UI and restart the API manager I get problems with:
AMQConnection Unable to connect to broker at tcp://10.16.0.5:5673
org.wso2.andes.AMQException: Error occurred while establishing a connection
I'm running 2.0.0 of API manager on Ubuntu 14.04
I don't have enough points to comment on a similar issue:
WSO2 API Manager - Error changing admin password
but happy to experiment and isolate this bug. I could try to change the admin password for all references in xml files under conf if needed.
Please advise on the best way to change the admin password for API manager. I'm happy to do a clean install and see if I can just change the admin password. Please advise if I should use the UI or change in repository/conf files.
Search all xml files with "admin" references. What I can recall is, api-manager.xml, user-mgt.xml, identity.xml, etc.. You may also check out the related wso2 doc.
I've just worked through this issue with WSO2 support. In my case it had to do with the content of the password. I used the same admin password for v2 as I did for v1.10 but apparently the different frameworks in v2 has a problem with special characters in the password. More specifically, a '#' character. The link below was provided as a reference. Upon changing the admin password, both in the console and in the user-mgt.xml file, and restarting the product, I am no longer experiencing the exception.
https://wso2.org/jira/browse/APIMANAGER-4991