How pkix profile works in Spring Security SAML - saml

I was reading the spring security saml doc site: http://docs.spring.io/autorepo/docs/spring-security-saml/1.0.x-SNAPSHOT/reference/htmlsingle/#configuration-security-profiles-pkix
I am just having a hard time to understand how the pkix profile works.
From my understanding, when idp sends back saml response, it will sign the response to show the validity of the message.
In metaiop, the SP will use the key from idp's metadata to verfiy signature on response.
Pkix seems like an extension of metaiop, it will do metaiop's check and also this:
All keys specified in trustedKeys set of extended metadata of a remote
entity, or all keys available in the key store when the property is
null (default value)
I just don't understand the above statement, what is the key store referred to in here? the local keystore?
I hope someone can clearify for me.

Keystore referenced in the documentation is the samlKeystore.jks of the sample application.
While MetaIOP needs to have the exact version of the certificate which will be used for signatures, PKIX uses verification based on trusted certification authorities (just like e.g. web browsers do) - which means you don't need to have the exact certificate used for signature in advance - as long as it's issued by one of the CAs you trust. PKIX also verifies e.g. certificate validity period (and other checks in certification path validation of RFC 5280 - https://en.wikipedia.org/wiki/Certification_path_validation_algorithm). Those are the key differences.

Related

Is Self-Signed IdentityServer4 signing credential good enough in production?

We are using IdentityServer4 and our version loads the signing key from a PFX file in file system or from the windows certificate store. Using the certificate works. The question is - which certificate issuer should be used in production?
Is a certificate from a public CA recommended? Or is it enough to have a self-signed certificate (without a CA at all) such as it can be created with IIS Manager?
In our tests we have found that the client could still validate the signature in the access token, even if the signing certificate would not have a valid CA chain on the client.
In the docs, it says that you can also use raw key material instead of a certificate:
http://docs.identityserver.io/en/latest/topics/crypto.html#token-signing-and-validation
In this scenario there would be no CA chain whatsoever.
That leads me to the assumption, that when the client loads the public signing key (via the HTTP(s) endpoint), the CA chain information might not be passed anyways. Is that right? Through the loading mechanism via HTTPs you also have a combined security mechanism.
So my conclusion is that for the signing credential a self-signed cert is just as safe as one from VeriSign. Can this be confirmed?
There is no certificate involved in signing and verifying the tokens. Only a private and public key (RSA or ECDSA key).
However a certificate can be useful to "import/transport" the keys into .NET. So, because of that we don't care about who issued the certificate.
When importing the key, one approach is to bundle the certificate that holds the public key + the private key and store it in a PKCE#12 file (.pfx/.p12 extension). Then load that file into .NET. Before .NET 5 working with keys was a bit hard.
The more important thing is that you can manage and deploy the private key in a secure way and that it is persisted over time.
Optionally, you can add support for key-rotation.

How can I specify a SHA-256 algorithm for signing the certificate?

I built an Apereo CAS demo server with a WAR overlay (with which
different services should be authenticated).
I have set up delegated authentication with SAML2 (for integrating
with italian SPID system), following this guide
https://apereo.github.io/2019/02/25/cas61-delegate-authn-saml2-idp/
I copied the SP metadata to a IDP configuration.
This IDP is a test IDP instance, meant to check if SP metadata and the SAML request are ok.
When I run the server and I browse it,
I can see the second login form, but when I click it, the validation checks shows some errors.
Among them there is the following:
"The certificate must be signed with a valid algorithm."
"The certificate must not be signed using the SHA1 algorithm (deprecated)."
I am pretty sure that SHA-256 would be fine with the IDP validator.
In the documentation
https://apereo.github.io/cas/development/integration/Delegate-Authentication-SAML.html
I see that the following parameter should be in charge of specifying
the signing certificate algorithm:
cas.authn.pac4j.saml[].signature-algorithms:
Its description is
# Required: false
# Type: java.util.List<String>
# Owner: org.apereo.cas.configuration.model.support.pac4j.saml.Pac4jSamlClientProperties
# Module: cas-server-support-pac4j-webflow
# Collection of signing signature algorithms, if any, to override the global defaults.
# cas.authn.pac4j.saml[].signature-algorithms:
I don't know what values are allowed there. I googled a lot but with no luck.
I have tried to set that list like this
cas.authn.pac4j.saml[0].signature-algorithms=["sha256WithRSAEncryption"],
cas.authn.pac4j.saml[0].signature-algorithms=["SHA256withRSA"] but,
after clicking the SAML login button, I always get the following
error:
org.pac4j.saml.exceptions.SAMLException: org.pac4j.saml.exceptions.SAMLException: Could not determine the signature parameters
at org.pac4j.saml.crypto.DefaultSignatureSigningParametersProvider.build(DefaultSignatureSigningParametersProvider.java:60)
...
How can I specify a SHA-256 algorithm for signing the certificate?

Wso2 - Change Resident Identity Provider to use different certificate other than wso2carbon

Could you please let me know how I can change the Resident metadata value to have a different certificate other than ws02 where I have signed a metadata using a specific cert. Seems IS is signing the SAMLRequest using its own cert so i get an invalid signature when sending a SAML Request to the Identity Provider.
I change the certificate alias on service provider configuration from IS console to the appropriate certificate but doesn't seem to overwrite signing it and still using the standard wso2 certificate.
Is there somewhere in the IS configuration where I can change the wso2carbon cert to one of my own so it will apply to identity provider resident?
Currently, the primary keystore configured by the / element in the /repository/conf/carbon.xml file is used for internal data encryption (encrypting data in internal data stores and configuration files) as well as for signing messages that are communicated with external parties. However, it is sometimes a common requirement to have separate keystores for communicating messages with external parties (such SAML, OIDC id_token signing) and for encrypting information in internal data stores. This is because, for the first scenario of signing messages, the keystore certificates need to be frequently renewed. However, for encrypting information in internal data stores, the keystore certificates should not be changed frequently because the data that is already encrypted will become unusable every time the certificate changes.
This feature will be available from IS 5.5.0 WUM and above. You can follow steps in [1] to configure multiple keystores.
<InternalKeyStore>
<Location>${carbon.home}/repository/resources/security/internal.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
<KeyAlias>wso2carbon</KeyAlias>
<KeyPassword>wso2carbon</KeyPassword>
</InternalKeyStore>
[1]https://docs.wso2.com/display/ADMIN44x/Configuring+Keystores+in+WSO2+Products#ConfiguringKeystoresinWSO2Products-second_keystore_internal_dataConfiguringaseparatekeystoreforencryptingdataininternaldatastores

How to validate Json Web Token (JWT) via Java-Jwt API?

I am new to oauth and JSON Web Token (jwt). I am trying to validate an authorization token (jwt) via Java JWT api (https://github.com/auth0/java-jwt). I was able to decode the header and payload via that API but having trouble to validate the token.
Little I know of this area, I thought I had to add jwks-rs-java api (https://github.com/auth0/jwks-rsa-java) to my test project in order to handle validation part so I imported and ran following statements based on the documentation I read.
The "oauth_server_domain" is Oracle Access Manager (oam).
JwkProvider provider = new UrlJwkProvider("oauth_server_domain");
Jwk jwk = provider.get("keyId_name");
Then I got following exceptions:
com.auth0.jwk.SigningKeyNotFoundException: Cannot obtain jwks from url https://<oauth_server_domain>/.well-known/jwks.json
Caused by javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I am trying to understand the problem itself and how to rectify it.
Did I provide wrong key id?
Do I need to import a certificate of the remote "oauth_server_domain" into my local box in where I build/execute project in IDE?
How to add ./well-known/jwks.json into oauth server (e.g. OAM)?
Update:
I do have a certificate (in *.der format) with a public key from the authorization server (oam). It seems like I need to manually create ./well-known/jwks.json file by following this guide (https://auth0.com/blog/navigating-rs256-and-jwks/). I think I should be able to convert binary encoded cert to base64 based cert (*.pem format?).
But how can I expose that relative path from authorization server (e.g. https://auth_server_domain:port/.well-known/jwks.json)?
I'd appreciate your advice and input on this matter. Thank you!

When .net says "certificate valid", what is it checking?

I'm using the SignedXml.CheckSignature(X509Certificate2, boolean) method. I would like to know what checks are performed when deciding the validity of the certificate. I have verified that the Current User/Not Trusted list is checked. The documentation says it will use the "address book" store, searching by subject key identifier, to build the certificate chain. I imagine this means the Local Machine and Current User certificate stores?
Am I right to think that certificate revocation and signature timestamp are not checked? To do an OCSP check for certificate revocation, am I obliged to use Bouncy Castle?
In the remarks in the msdn article you link to one finds:
In version 1.1 of the .NET Framework, the X.509 certificate is not verified.
In version 2.0 and later, the X.509 certificate is verified.
In version 2.0 and later of the .NET Framework, the CheckSignature method will search the "AddressBook" store for certificates suitable for the verification. For example, if the certificate is referenced by a Subject Key Identifier (SKI), the CheckSignature method will select certificates with this SKI and try them one after another until it can verify the certificate.
Thus, first of all the behavior of that method has changed in different .NET framework versions. So for reproducible results, you had better not count on that method even check the certificate at all.
Furthermore, the formulation try them one after another until it can verify the certificate sounds like there just might be the mathematical test whether or not the certificate is signed by its alleged issuer.
https://referencesource.microsoft.com/#System.Security/system/security/cryptography/xml/signedxml.cs,b9518cc2212419a2
It checks
The certificate has no Key Usage extension, or the Key Usage extension has either Digital Signature or Non Repudiation usages enabled
The certificate chains up to a trusted root authority
The certificate has not been revoked
The certificate was not expired when you called this method
It doesn't know when the document was signed, so it doesn't answer that question.
That none of the certificates in the chain are explicitly prohibited by the user or system configuration.