Azure APIM - how to validate client certificate using context.Request.Certificate.Verify() - azure

I am trying to validate a client certificate in Azure API management using context.Request.Certificate.Verify() method.
I have tried the following steps:
I have created self signed root CA certificate and then created a
client certificate and key file.
Now from postman, I am trying to call a method attaching the client certificate. I have verified that the certificate is sent to APIM via trace.
Have uploaded the root CA certificate in APIM -> CA certificates. While uploading I
converted to ".cer" file as it is not accepting ".crt" file and set the Store as "Trusted root".
In APIM policy, have used the method to validate the client certificate via context.Request.Certificate.Verify().
Now, when I try to call APIM api with client certificate, the above method (step 4) is always coming as False, verified from apim trace. Not sure, what and where I am doing wrong things. Any help/guidance or any article is really helpful.

I faced the similar issues, Investigation Summary / Cause are below:
Later customer encountered issue again when they sent PFX certificate as a client certificate to APIM from Postman.
The self signed certificate CRL distribution list (Urls in certificate revocation lists) and Access information cannot be publicly reached (APIM is public hosted and not internal) hence certificate.verify fails
2 options to fix the issue
Purchase a certificate from a Public trusted CA
Use context.Request.Certificate.VerifyNoRevocation instead of context.Request.Certificate.Verify so that APIM will not check the revocation list during certificate.verify
Note:
If certificate.verify is a mandatory order from your security team, then you would have to purchase a certificate from trusted CA
o you need to VerifyNoRevocation since apim cannot retrieve revocation list information and VerifyNoRevocation will still perform verifying certificate path as well

For client certificate validation in Azure API management generally following steps are required.
Generate a root CA , intermediate CA along with the client certificates.
Upload the intermediate certificate which validate client certificates sent by the user.
You van utilize this guide to set up the CA.

Related

Azure KeyVault generated certifcate is showing Not Valid in Browser

Created a self signed certificate in Azure KeyVault as below with DNS
Azure KeyVault Certificate
Have added the certificate to Azure Kubernetes Service as a secret using secret-store-csi-driver and added to ingress
Problem is while opening the DNS in browser it shows certificate is not valid as below
Certificate Not valid
The Certificate is already added to Trusted store and shows as below
Certificate Details
Certificate Details
Also, the certificate in browser is the one in Azure Keyvault certificate as evident from the validity date
What could be the issue?
When you use self sign a certificate, your Operating System or Browser wont trust this Cert, as it is self signed and considered insecure for the Internet.
You need to use a Cert from a valid Certification Authority or import your CA root cert that created the cert into your OS or Browser. But every user need to so this.
A better approach is Cert-Manager ff you are using AKS. Cert-Manager can issue certificates from LetsEncrypt. Here is a workflow from Microsoft for this.

Azure API Management - Client Certificate Authentication Responsibilities?

When using Azure API Management Gateway its possible to implement client certification authentication to secure access to APIs. You can validate incoming request certs using policy expressions such as thumb checks etc.
When using client cert authentication method, what's the recommended process for certificate generation/management?
Cert responsibility?
Should I/gateway owner be generating the .pfx file (either self signed or by trusted CA), importing it to the gateway service and providing external clients with the .cer to install locally and auth with?
Should I/gateway owner be generating the .pfx file (either self signed or by trusted CA), importing the .pfx to the API Management gateway service (normally I'd imagine importing the .cer on a server/gateway but doesn't seem possible in Azure) and providing external clients with the .pfx to install locally and auth with?
Should the external client be responsible for generating their public/private key pair in their Org, signing it with a CA, installing it locally and providing me/gateway owner with a .cer file to import to the gateway (as above, not sure its possible to import .cer, I read only .pfx accepted in import process) or provide thumb for me to store/validate in policy?
Does anyone have any advice whether to issue clients requiring access to the same API the same (shared) cert or generate a new cert per client? They would all be using the cert to access the same API (+ additional auth methods, cert is just an extra step).
I've ready online tutorials describing all above bullets and where client-specific or single cert-per-API have been implemented so a little confused which is recommended approach?
The easiest way would be to have a single issuing CA certificate, you'd only need to upload its public key to APIM as that is all that's needed for APIM to validate incoming certificate. Then you'll be responsible to generate client certificates and distribute them to clients. In APIM you can setup a policy that would require certificate, check its issuer and validate, that should be enough to ensure that certificate is valid and issued by you.
Relying on self-signed certificates will be a hassle as you'd have to somehow let APIM know of each new certificate, having common issuing CA frees you of that worry.
Same goes for allowing remote clients to generate certificate - they would have to let you know of certificate and you'd need to list it in APIM one way or another.
You're free to decide how exactly to distribute certificates, a few things to consider:
Likely certificate will be your main way to tell clients apart. If that is important you may want to have different clients have different certificates.
If you want to deny access to a particular client you'll "revoke" that certificate, you need to make sure that other legitimate clients won't be affected.

How to verify my client certificate with the Root CA certificate in Azure API Management inbound policy?

I have to take my Root CA from Azure key vault inside the Azure APIM inbound policy and verify my requested client certificate inside the policy.
For this I have followed the link and able to get the certificate
https://github.com/galiniliev/api-management-policy-snippets/blob/galin/AkvCert/examples/Look%20up%20Key%20Vault%20certificate%20using%20Managed%20Service%20Identity%20and%20call%20backend.policy.xml
But I am not able to validate the client certificate by using My Root CA that I have fetched from Azure key vault
Following is the values of Root CA that I am getting from Azure key vault
{"id":"https://newdev-keyvault.vault.azure.net/certificates/MyRootCA/bf34888e**********","kid":"https://newdev-keyvault.vault.azure.net/keys/MyRootCA/bf34888e*************","sid":"https://newdev-keyvault.vault.azure.net/secrets/MyRootCA/bf34888**************","x5t":"gYbnPUooh4D5_ogrmWCEvfDjYXo","cer":"MIIDFTCCAf2gAwIBAgIUJYAgKiqYPh+Iq1DFULomUlhzNTAwDQYJKoZIhvcNAQELBQAwGjELMAkGA1UEBhMCSW4xCzAJBgNVBAoMAlwuMB4XDTIwMDQxNjA4MTgyOFoXDTMwMDQxNDA4MTgyOFowGjELMAkGA1UEBhMCSW4xCzAJBgNVBAoMAlwuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs2EOpy+GxPFCidiW5hGPVlPXuZFfgJdZWITLkUQ2SvcuBfLSsKmPkSpYO7TAFESpBWD0z8y3BYat0hGA2iBhMWzXN0dhbB+bZ6uDdrg0kuGaFmb4fmQ9mydM7cy3NtZA6lf5uTp9RZV4wiUVyKrRgGRzKUxecnFmtCOyk+jeW/Jf38laN1l84eM47UaMJjWD9vg/3QsW3yH+8zst2gWfXN7giQFRCMnzYTRD0VOd3N+C3k2mx72d4DobwbsngIclDHK0BFUckdK8MaOVIixRRQjFTZ/XjRqhPOCZRbgHHldXfx352eYqzOfYOi/utv8s6Xwl/0TI3uj2RTth7CwJkQIDAQABo1MwUTAdBgNVHQ4EFgQUZZMEGpRcswKq23a52gqebZcnloAwHwYDVR0jBBgwFoAUZZMEGpRcswKq23a52gqebZcnloAwDwYDVR0TAQH/BAUwAwEB","attributes":{"enabled":true,"nbf":1587025108,"exp":1902385108,"created":1587036499,"updated":1587036499,"recoveryLevel":"Recoverable+Purgeable"}}
Can anyone help me to verify the client certificates inside the Inbound policy?
Certificate you obtain dynamically from AKV cannot be used at the moment to validate client certificate from request. The only way is to upload CA certificate to APIM and then call .Validate on request certificate. That will require you to export certificate from AKV and refresh it in APIM every time it changes.

Mutual authentication - setup, flow, verification

I am implementing mutual authentication between a single client hosted app (CLIENT) and my spring boot 2 application (SERVER). I understand the steps to be as follows:
The server generates a keystore and truststore. The keystore being used for storing the server's certificates and private key. The truststore used for storing other credentials (certificates from certificate authority (CA) or trusted client certificates).
A CSR is raised for the server which is then passed to a CA. The CA generates a signed certificate from the CSR. This is the installed in the server keystore.
The client (which has it's own keystore and truststore) provides their public key to the server. This is then installed in the server truststore.
When a https request is made from client to server:
The client makes a request to access a protected resource.
Server responds with their public certificate.
Client verifies that certificate (looks in truststore and checks if it signed by a trusted CA).
Client presents their public certificate to server.
Server then verifies certificate against their truststore.
Assuming verification success client is granted access to the protected resource.
So I have a few things which I'm a bit confused about...
Are the steps outlined above broadly correct?
How does the server verify the client certificate? (I think it looks at the truststore for that certificate but not sure what actually happens after that).
I've seen examples of the CA certificate being installed in the server truststore instead of the actual client's public certificate ~ is there a use case when this should or should not be done? For my use case I have been provided with a signed certificate from the client (third party). The CA who signed that is different from the CA who signed the server certificate.
Does this process actually authenticate the client i.e. this client can now have access to the servers protected resources but another client who might present a different certificate will not have access? (like a more secure method of providing a username and password)
Where does common name (CN) checking come into all of this? I note in Spring Boot X.509 you can derive a username from the CN and then use this to lookup the appropriate user details from the user details service.
If the client certificate gets compromised for whatever reasons is this managed by just removing it from the server's truststore?
Is there an advantage, in my scenario of using a trusted CA e.g. verisign to produce a client certificate over a self-signed one? i.e. the certificate is passed to me directly from the trusted third party, and then installed.
In respect to your first question, yes your outlined steps are correct! Here is the general mutualSSL flow with a graphical overview: (source)
A client requests access to a protected resource.
The server presents its certificate to the client.
The client verifies the server’s certificate.
If successful, the client sends its certificate to the server.
The server verifies the client’s credentials.
If successful, the server grants access to the protected resource requested by the client.
Your second question (How does the server verify the clients certificate?):
The server verifies the clients certificate with the help of the signature. The signature is usually a hash-value, build of the complete certificate. The hash-value is signed with the private key of a corresponding CA (certificate authority). The server verifies the signature of the client certificate with the help of the CA's public certificate.
Your third question (Servers truststore containing the clients public key/certificate or the corresponding CA certificate?):
If you use for example self-signed certificates, you probably have to import the clients public key/certificate directly into the servers truststore. If your client uses an CA signed certificate, it is appropriate for you server to store the CA public key/certificate only, because it is used to verify the clients certificate.
Your fourth question (Does this process actually authenticate the client): Yes! As you can see in the answer to your second question, the certificate is verified by checking the signature. The signature is a hash over the complete certificate. A standard X.509 contains information to identify the subject. By checking the signature the subject is authenticated. A standard X.509 certificate contains amongst other things e.g. this information:
Subject name, Subject Public Key Info, Public Key Algorithm, Issuer Unique Identifier (optional), ...
Your fifth question (Where comes CN checking?): The CN (common name) verification is executed during the certificate check. The CN identifies the valid hostname for the current certificate. It is limited to one entry. As an extension the SAN (subject alternative name) was introduced. A certificate can contain more than one SAN. The CN (and the SAN) entry is part of the certificate and is verified with the help of the certificates signature check.
Your sixth question (If the client certificate gets compromised for whatever reasons is this managed by just removing it from the server's truststore?): Therefore the CAs use so called revocation lists. If you are using for example self-signed certificates it would also be okay to just remove the compromised certificate entry from the servers truststore.
Your seventh question (Is there an advantage, in my scenario of using a trusted CA e.g. verisign to produce a client certificate over a self-signed one?): There exist a few advantages of using a CA signed certificate instead of self-signed ones.
The certificate and eventually the revocation is managed by the CA
The certificate is valid to every relying party of the public CA, e.g. Verisign
Most of the public CAs offer standardized ways of creating a certificate

Azure SSL Binding Issue- No match seleted hostname

I bougth a SSL certificate online from a seller today for my custom domain which redirected to the azure web application with cname.
I did created csr file with that domain let's call it app3.product.com by using IIS 8.And then created the .crt filel with that csr file.
After that i did found that i need the pfx file but i didn't have .key file so, i converted the .crt to .cer than uploaded it by azure portal.
The problem is Azure portal says,
No certificates match the selected hostname
Althogh my certificate issued as app3.product.com and the host name has the same domain name. It doesn't work.
I didn't include key file while i am creating the csr file also the subject of the certificate has some additional information by the issuer. The subject like app3.product.com, Certificate Issued By ... These may be the source of the issue.
Thank you in advance.
You need to include the private key. Otherwise your web server can not decrypt the data the clients (web browsers) are sending to it.
Explanation:
HTTPS/TLS/SSL are based on asymmetric cryptography which means that data gets encrypted with a so-called public key and can only be decrypted with the corresponding private key.
This means that your web server will send a certificate to the browsers which contains the domain name + the public key + a signature from a Certificate Authority (CA). The web browser then checks then if this certificate is valid (with a CA certificate) and uses the included public key to encrypt further data. Since your web server is the only one who knows the private key it can use it to decrypt the web browsers request. Actually the overall process is even a little bit more complex. You might want to have a look at the TLS handshake protocol to see how it works.

Resources