how to use two separate SSL certs when my app calls different endpoints?
hey guys. i have a spring application. there are two endpoints that are being called in it (for example
endpoint1
and endpoint2
). and also there are two security certificates (for example cretificate1
for endpoint1
and certificate2
for endpoint2
). i have a problem. how to switch between certificates? because once the application is running, the JKS is already loaded. how to approach this issue? thanks in advance.55 Replies
⌛
This post has been reserved for your question.
Hey @bambyzas! Please useTIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here./close
or theClose Post
button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
A jks can contain multiple certificates. You could put both certificates into the one keystore and the Endpoints will decide what certificate to use by themselves.
💤
Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived.
If your question was not answered yet, feel free to re-open this post or create a new one.
In case your post is not getting any attention, you can try to use /help ping
.
Warning: abusing this will result in moderative actions taken against you.
really? i had an idea about being able to load both certificates into the keystore and reference the one i need at any given time with an alias
shouldnt i be using SSL bundles?
Have you installed the KeyStore Explorer? It is a very nice tool.
sure, i have it
i have set up my jks with two certs long time ago
so this part is done
but i dont know what to do next
Start the app and try to use the endpoints. Are there any exceptions?
app starts fine
but wait there for a minute. how is Spring gonna decide which certificate to use for which endpoint?
i just want to understand
Is it a incomming connection to your app? Is it a outgoing connection from your app?
um, idk tbh. my app is running, and then it will be making calls to the 3rd party endpoints. so as i understand its outgoing connection
ok, then it is an outgoing connection from your app.
Well we have 3 phases.
1. Handshake
2. Certificate check
3. Key Exchange.
Here is a good tutorial:
https://youtu.be/j9QmMEWmcfo?t=194
In stage 3 the keys decide what certificates are used for data-transfer.
In phase 1 the TLS asks what chiphres should be used, what encoding algorithm should be used and what blocksize should be used for data-transfer and key-interchange.
In phase 2 the endpoint guarantees to your app that he is authentic.
In phase 3 your app send the signatures of all certificates your app knows, the endpoint then report what signature matches best, then your app use the according certificate.
Then you have a TLS session (aka ssl-session).
btw: in the video your app is the "client" and the endpoint is the "server".
In phase 3 your app send the signatures of all certificates your app knows, the endpoint then report what signature matches best, then your app use the according certificate.
okay, but if i have completely different endpoints with different hosts? like facebook.com/endpoint1
and google.com/endpoint2
?when you init a tls handshake with the target, it presents a certificate
java will check all
trustedCertEntry
s in the keystore you supply to find one that matches
you don't have to specify which cert to use for which endpoint because if there is any matching trusted in the truststore you supply it will automatically be selectedbut there are two completely separate targets with separate hostnames. how does the target know which cert to choose?
it will just blindly check trustedCertEntry?
not blindly; it will look for a cert that matches what is presented by the server
example from google.com (with javax.net.debug=all):
server presents:
client finds a match:
wait. so i can just dump all my certs into one jks, and i can just call two completely different apis and everything will be fine?
this is how java works with all other certs with a magical massive jks called
cacerts
check $JAVA_HOME/lib/security/cacerts
- it's a jks which has hundreds of trusted cert entries, mine has 139 for example😦
this is windows so for you it would be
%JAVA_HOME%
but only if you've configured that as an env var
wherever you have java installed look in lib/security/cacertsi dont have such env var
it doesn't matter i was just highlighting how all other "well known" certs are handled in java
can you explain this? i dont understand how to read it
and why is it a match like u said?
1. server says "here is my cert chain"
2. client says "i recognise this chain of certs"
hence can be trusted
and why is it a match like u said?
because the signatures match between the cert presented by server and one stored by client (in this case in
cacerts
)but you are sending one certificate here
google is sending a chain of certs (one signed by the other all the way up to a self-signed root CA) - i can't show all here because of discord limit
ok
my client is recognising a part of the chain (i don't need to trust the whole chain) all the way up to the same root CA, with the same signatures
if i trust your signer i don't need to explicitly trust you
but here i cant see
trustedCertEntry
field that u mentionedthat's from the output of keytool, unrelated to this debug stuff
but it's loading those trusted cert entries from the jdk's cacerts
but wait. java app isnt sending jks
its sending one cert to the api
you're now describing mTLS (mutual TLS)
where the client sends a cert
um, yes
ok so that's the keystore not the trust store
yes. i never said such thing as
trust store
in the mTLS case, after the stuff i mentioned relating to trust, the server sends a request to the client called a
CertificateRequest
which says "you must present a certificate satisfying these requirements"yes
but similar to the trust store java looks into its configured keystore to find a key that matches the certificate request
so you can have multiple private key entries in the same keystore and java will select the right one depending on the CertificateRequest it received from the server
oh, now it makes sense
here's an example of a CertificateRequest (from https://certauth.cryptomix.com/json/ ):
in this simple case the only requirement is to send a client cert signed using one of the signature schemes in the list, but in real life the CertificateRequest asks for a cert signed by a specific CA with a specific signature
in this case i didn't present a cert:
usually this leads the server to hang up on you but in this testing server's case it accepts it anyway and returns a 403
okay. but what would happen if my api provider changes root cert?
if you mean the root cert that it uses in its CertificateRequest, then you have to get a new cert signed by that new CA and update the keystore
no, i mean root certificate in general
you know, companies sometimes change their root certs. thats what i meant
companies change their edge certs all the time but this doesn't affect your setup since they will be signed by the same small handful of root certs and that signer/root cert chain is unchanged
changing the root cert is usually a once-in-a-decade major exercise
but also if that root cert is a well known one e.g. verisign/GTS/ISRG/etc then updating the jdk will update the cacerts
current root cert is
CN DigiCert Global Root CA
. but soon it will be changed to digicert global g2 tls rsa sha256 2020 ca1
. so the signer (like u said) will not remain unchangedbut will you have a new cert to identify with?
if the signer changes you need a new client cert
(and therefore need to update your keystore)
idk if signer changes. as i understand it remains the same
DigiCert Globalb
?if signer changes then old cert signed by old signer will no longer be valid
unless if only server side is changing but client CertificateRequest (mTLS) doesn't
can you provide me some info/resources on that? bc i tried googling and couldnt find any info 😦
Unknown User•7mo ago
Message Not Public
Sign In & Join Server To View
hi
Unknown User•7mo ago
Message Not Public
Sign In & Join Server To View
I was bizzy but I see @imp_o_rt took it just right. Thanks.
💤
Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived.
If your question was not answered yet, feel free to re-open this post or create a new one.
In case your post is not getting any attention, you can try to use /help ping
.
Warning: abusing this will result in moderative actions taken against you.