What I understand so far:
The CA(Certificate authority) has a key and builds a certificate using that key
The server has a key and builds a csr(Certificate Signing Request) with that key
Then using both the CA crt and key as well as the server csr the CA builds a server certificate
To authenticate a server the client uses the CA (its certificate) like this:
4.1. The client receives the server certificate
4.2. The client verifies that this certificate is authenticated by the certificate of the CA that it has (using the public key of the CA), it also verifies that the serial number of this certificate is not in the CRL (certificate revocation list)
4.3. The client generates a symmetric key and encrypts it using the public key giving by the server and sends it to the server
4.4. All communication starting from now is then encrypted using this symmetric key
Here is where I am still a bit confused:
The client uses the CA public key to verify the server certificate in step 4.2 but how does a match occur since the client only has the certificate of the CA? I mean unless the server csr passed to the CA has the same information verified by the client as the crt of the CA that the client has, how can a match occur?
Since anyone can have the server certificate I am assuming the only step that insures that only the server can communicate with the client is step 4.3 where only the server can have the symmetric key because only the server has the private key so only it can decrypt this encrypted symmetric key. Is this correct?
I am also not sure of all the steps or if I missed any steps.
I found an answer (How are ssl certificates verified?) that responds to the first part of my question then luckily someone posted a link in the comments that answers the rest: http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html
Related
I am searching the algorithm about how SSL validation process is performed, but almost everywhere, they explain the certificate validation step as "certificate is checked by client" or something like that, but I wonder what is the scenario behind this.
What I know is:
When the client receives a copy of the certificate that belongs to which website/server you wanna attempt to handshake, there are some indicators that shows the public information of webserver (I think this is for matching the entries in your cached certificate entries, which your browser has installed.)
Once the client matchs a cached-certificate with the webserver's one, it starts validating it. It uses the public key of cached-certificate to decrypt the signature of webserver's one.(? [Not sure this because public keys are used to "encrypt" the data, not decrypt. Also this step may be totally wrong.])
Once it decrypts, it compares the signature between cached one and webserver's one. If it is same, certificate is valid.
I also heard about chains. I really wonder how a chain is known, and how to determine if the webserver's certificate just belongs to a chain.(?)
How SSL certificates are checked by client? I need the answer as step by step and clarified. Thanks :)
Edit:
I think the public key here is used for "decrypting" instead of "encrypting". So a public key is not responsible for encrypting everytime, it can also decrypt and don't encrypt some data. The magic here is that since the public key decrypts here, if you want to fake the certificate, you should have that CA's private key to apply the changes as encrypted (because only private key can encrypt the data). But now, another question comes... What if we decrypt it using webserver's public key, then change the entries in the signature, then encrypt it again using our own private key (we generate it manually, it doesn't belong to server.), which actually make us behave like a CA; and finally overwrite the certificate to hold our own public key which is able to decrypt the data encrypted with our own private key?
There is differences between Encryption and Signature.
Public Key is used by the client to encrypt data that only the server can decrypt with the Private Key of the server.
Public Key is used by the client to verify the signature of the data send by the Server that can only be signed by the Private Key of the server.
When the client wants to access a server, the server send you a certificate containing a public key. The client usually the web browser will check in his integrated CA's list certificates if it contains it.
If it contains it, the client continue and get the CA(Certificate authority)'s that authorized this certificate.
If it not found but the verification of the signature pass, the client will get a warning saying that the certificate is probably self signed and can be malicious.
If the client can't verify the signature, it means the certificate is not valid.
for the chain of trust you can check wikipedia :
https://en.wikipedia.org/wiki/Chain_of_trust
you need to be in this chain of trust to be register in the web broswer integrated "database" of CA's.
Hope it answers your question, best regards,
M
Put it simple:
Private Key -> Decrypt and Sign
Public Key -> Encrypt and Verify
Certification Authority
Is the authority that signs and guarantees the authenticity of the certification. If you trust the CA, then you trust also its certificates.
It's the same for friends: if you have a friend that you trust and this tells you "I have a friend that I trust", then you also trust the friend of your friend.
Chain of Certificate Authority.
You can have multiple intermediate CA, for example, you can have
Root Certification Authority
Intermediate Certification Authority for WebServer signed by Root Certification Authority
Web Server Certificate signed by Intermediate Certification Authority for WebServer
Intermediate Certification Authority for signing code, signed by Root Certification Authority
Etc
Why?
Because in case one of the intermediate authorities is compromised you can revoke only its child certificates.
At the enterprise level, each CA has a different level of security, for example, the Root Certification Authority can be stored inside a safe and used only when there are two o more admins.
For the intermediate, instead, maybe only one Admin can manage it.
References
How SSL Works
How HTTPS Works
Wht digital certificates
I'm doing my best to understand mutual SSL. One question I can't find a good answer to is why you need to create a key pair on the client instead of just providing a public client certificate.
So far I understand the following (very oversimplified):
Regular SSL:
The server has a key pair and sends the public part (certificate) so the client can use that public key to encrypt messages so they can share a symmetric key and eventually secure all communication.
To verify that the server is actually the server the issuer of the certificate has to be trusted (in a truststore) of the client by default.
Mutual SSL:
Exactly the same, only this time the server asks the client to authenticate itself.
The client sends its public certificate, which is verified against some kind of list of "known certificates" on the server. If it matches, communication can continue.
I don't understand why I have to include the entire key pair (the private part as well) in the key store I use on the client side. Where is the client's private key used in the process?
The server has a key pair and sends the public part (certificate) so the client can use that public key to encrypt messages so they can share a symmetric key and eventually secure all communication.
That's not the main point of the server certificate and with modern key exchange methods (i.e. Diffie-Hellman) the certificate is not involved at all in the key exchange. What you describe is only true for the obsolete RSA key exchange.
The main point of the certificate is to be used for authentication. Authentication means that the server proves that it owns the provided certificate and then that the client verifies that the certificate matches its expectations, i.e. issued by a trusted CA, expected subject/SAN, not expired etc.
The proof of ownership is done by signing some data (which is at least in part provided by the peer, i.e. client) with the private key matching the public key in the certificate. The peer (client) then can verify this signature using the public key of the certificate and if the verification passes the other side (server) is obviously in possession of the secret private key which means it owns the certificate.
With a client certificate used in mutual authentication the procedure is exactly the same, only with switched roles. That's why the private key is needed on the client side.
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
I would like to know what are the exact steps of certificate authentication over HTTP.
I know this has been asked before, but from what I've read it's still unclear to me how it works.
When first contacting the secure site client will send its certificate
This will be his public key ( let's say a public_key.pem file begginging with ----BEGIN PUBLIC KEY---- )
Server will look whether this certificate has been signed by a trusted CA.
The server only has a list of certificates which it trusts (you configure this keystore when configuring SSL). That is where all private keys are stored. Is this equivalent to all the trusted CAs of the server?
The next step now is to take the public_key.pem and check whether any of the certificates in the keystore have signed it.
If the above process is accurate:
First question: A 'certificate' is a private key signed by another certificate ( or self-signed )
Second question: How exactly does a server validate that a public key was signed with a specific private key ( certificate ) ?
Third question: 'certificate' A can be used to sign another 'certificate' B, consequently 'certificate' B can be used to sign certificate C and so on. If my server has certificate A in its truststore, it means it will also trust public keys coming from certificate B and C ?
Edit based on answer below
My server has cert.pem and privkey.pem. The cert.pem ( x509 certificate ) has been signed by a trusted CA using its private key ( the 'signing' process involves the CA to do 'something' with its private key and sign my Certificate signing request ).
When SSL is negotiatied my server will send the cert.pem to the client ( in some form ). How does the client determine that my public cert was signed by a trusted CA. My truststore pb only contains other public certificates of trusted CAs, so it ends up checking whether my cert.pem was signed using only public certificates of trusted CAs.
This is is the part which is unclear - and I may be missunderstanding the whole process - can a client check if my x509 certificate is valid by just having an x509 list of certificates of trusted CAs?
When first contacting the secure site client will send its certificate
A client doesn't have to send a certificate. Judging from your question, it doesn't sound like you're asking specifically about client-cerificate authentication. In many sites, like if you go to google, stackoverflow, facebook, etc, the client / browser will not send a certificate.
A 'certificate' is a private key signed by another certificate ( or self-signed )
Not quite. A certificate contains a public key that is signed by the private key that corresponds to another certificate.
I think this is worth clearing up. A certificate itself will only ever contain the public key, or the "Subject Public Key Info" in x509 parlance. There is a corresponding private key to that public key that is stored separately from the x509 certificate.
There are some formats that "combine" the certificate and the private key in to a single file, but at this point it isn't a certificate anymore, it's a file containing a certificate - an example of this is PKCS#12. This is a format that can store as many certificates and private keys as needed.
A private key may not even necessarily be a file on disk - it could be in a Hardware Security Module, SmartCard, etc.
'certificate' A can be used to sign another 'certificate' B, consequently 'certificate' B can be used to sign certificate C and so on. If my server has certificate A in its truststore, it means it will also trust public keys coming from certificate B and C ?
Yes. This is called a certificate chain. A is the "root" certificate, B is an "intermediate", and C would be an "end-entity" or "leaf" certificate.
This is very common among HTTPS certificates by CAs. Certificates are never issued directly off the root, they're issued off the intermediate.
How exactly does a server validate that a public key was signed with a specific private key ( certificate ) ?
Well this makes the assumption that a certificate is a private key, which it isn't.
The server, as in the thing serving HTTPS, doesn't really care about the validity of the certificate. It's up to the client to decide if it should trust the certificate the server gives.
The server has the certificate and the corresponding private key. The server can validate that the public key and the private key belong together. How this is done depends on the key type, but the gist of it is, if you know the private key, you can fully reconstruct the public key from it. The server will validate that the private key's "public parts" match the certificate's public key.
The server will present the certificate to the client, like a browser. The browser will check many things, but at minimum it will check two important things:
Can the browser build a chain back to a certificate in the trust store. So the browser will look at the signer of the certificate, called the Issuer, and check if the issuer is in it's trust store. If yes, then the certificate is trusted. If no, it will see if that certificate has an Issuer, and loop all the way down the chain until it reaches the end of the chain, or when it finds something in the trust store. If it reaches the end, then the certificate was not issued by anyone it trusts.
That the certificate is valid for that domain. The certificate contains a Subject Alternative Name (SAN) which indicates what domains the certificate is valid for.
There are lots of other things that get checked, like expiration, revocation, Certificate Transparency, "strength" of the certificate - too many to list.
How does the client determine that my public cert was signed by a trusted CA.
Every client has its own trust store. Internet Explorer on Windows uses the Windows trust store, Google Chrome on macOS and Windows use the operating system trust store (Keychain, Windows Trust Store, etc).
The browser / client needs to build a trust path, as described above. How it does this is a bit complex, but it works out to the Authority Key ID attribute - if it exists, and the Issuer property of the certificate. It uses these values to find the certificate that issued it.
Once it finds the issuing certificate, it checks the signature on the certificate with the issuer's certificate public key.
That issuing certificate could be in the "root" trust store, and uses the public key in the issuing certificate to verify the signed certificate.
Your web server might (probably) send intermediate certificates along with the "main" (leaf) certificate. The client might use these intermediates to build a path back to a certificate that is in the root trust store. Intermediates can only be used as intermediates - you can't send an additional certificate saying "here's the root certificate, trust it".
can a client check if my x509 certificate is valid by just having an x509 list of certificates of trusted CAs?
Yes. That is the trust store. Every browser has / uses one. Firefox has their own trust store called NSS. Operating systems typically have their own trust store, too.
My question is about certificates specifically in ssl but I think the questions should apply to all certificates. I have included the SSL procedure for the sake of clarity.
In SSL this is what I understand the procedure is:
1)Client
sends supported crypto algorithms
sends client nonce
Server
chooses (and sends) a
symmetric algorithm
a public key algorithm
a MAC algorithm
sends it's certificate
sends server nonce
Client
verifies certificate
Extracts public key
Generates a pre-master secret key (pms)
encrypts with servers public key and sends
Client and Server
compute master secrete (MS) from PMS and nonces
PMS sliced to generate two encryption & two mac keys
Client
sends a mac of all handshakes (to ensure they were not previously modifide)
Server
sends a mac of all handshakes
Question
What stops a man in the middle attack from happening at step two? Why can't a man in the middle, say trudy, capture the certificate sent by the server and change the public key in it (to something it has the private key to).
I assume that the certificate is encrypted somehow.
However the server cannot encrypt the certificate because the client does not have the public key yet. When the server gets the key from an authority (like veri-sign) would the key be pre-encrypted using verisign's public key? I think this should work because all web browsers should have the public keys of most authorities.
No, the certificate is not encrypted. But it is signed by a certification authority (CA). Since those check the information included in the certificate (especially the URL to which the cert belongs), there shouldn't be a second valid certificate for a given URL.
The cert of the CA is checked against a trust store (e.g. in your browser). If this truststore is compromised, or if you trust not valid certificates, there is no protection against man in the middle attacks
Certificates are signed by some trusted authority, such as Verisign.
The certificates for these root authorities are built right into the browsers when you download them. You can view the root certificates in Firefox, for example, by going to tools-->options-->advanced-->encryption-->view certificates-->authorities.
If any one of these root-certificate authorities is compromised, however, you are right that a certificate could be forged, making a man-in-the-middle attack possible.
You actually pointed out a weak spot of PKI.
Say Trudy is in the middle of you and yourbank (bank.com). Trudy can change the public key at will at step 2 but the certificate's signature will be invalid. So Trudy has to find a way to generate the signature again. It's safe to say that the trusted CAs will not do this for him. So he has to sign with a fake CA, which is not trusted by your browser. This is still safe theoretically.
However, most browsers (especially IE 6) display a vague security warning and most people don't understand and just ignore, according to some tests.