How does authentication with client certificate work - authentication

I am developing a service which I will deploy behind an ssl terminating proxy inside a private network.
SSL is NOT used inside the private network.
The client of my API wants to pass their certificate in a header. We are NOT going to use mutual TLS.
Once my service receives a request with a certificate in a header, how should I validate it?
My understanding is that:
The client's certificate will contain their identity, public key and a signature of a Certificate Authority.
Once I receive their certificate I should be able to verify that it is indeed legit with the public key of a Certificate Authority.
But how should I verify that the client is who they claim to be and not simply replaying the certificate? I could, in theory, challenge their certificate by encrypting something with their public key and then asking them to decrypt it but this will require additional steps.

Client will also send some signed content (say signed userid or signed token) and you can use public key to verify signature. If Signature is verified, it proves that sender owns the private key for the public key he had sent.

Related

Secure Authentication using Digital Certificate and Digital Signature

I am developing authentication through the PKI. I am new to authenticate the user through the PKI so after reading on internet i came up with this solution. A user will create a public and private key. To validate the public key the user will apply for the Digital Certificate. The Digital certificate will have the public key, the meta data of the user and the Digital Signature of the Certificate Authority. To prove no data tampering the user will use the Digital Signature which will be the hash of the certificate with the private key of the user. The user will send both the Digital Certificate, Digital Signature and the data to the server.
The server in response verify the Digital Certificate and grab the public key to validate the Digital Signature and after verification the Server will encrypt the data using Public key and send to the user. I am also using https for the secure transfer of the information.
Now I am confuse how this will be done pragmatically.
From where I can get the Digital Certificate, majorly which are the trustful CA ?
Is there any REST API by the Certificate Authority where I send the certificate to validate a certificate?
Is there any library to parse the certificate to extract the information?
Sorry I am newbie in the Digital Certificate and Digital Signature.
To prove no data tampering the user will use the Digital Signature which will be the hash of the certificate with the private key of the user.
No, the digital signature is generated over the message data using the private key. The certificate is used to verify it
The server in response verify the Digital Certificate and grab the public key to validate the Digital Signature and after verification the Server will encrypt the data using Public key and send to the user. I am also using https for the secure transfer of the information.
you should associate the public key to the user account during registration process
with https, additional encryption is redundant and useless
encryption with public key (assuming RSA) is limited to key size.
From where I can get the Digital Certificate, majorly which are the trustful CA ?
Each browser has its own trusted list. Additionally in EU exists a list of qualified certificate providers. The lists are different.
You can also build your own CA
Is there any REST API by the Certificate Authority where I send the certificate to validate a certificate?
the message format to request a certificate is standardized (pkcs # 10), but the connection protocol with the CA is not. It is possible that a CA has REST services, but in any case, a certificate will never be issued by the CA without validating the user data that is included in the certificate
Is there any library to parse the certificate to extract the information?
Of course, search for your programming language

Digital signature man in the middle attack prevention

I have client-side generated a digital signature(JavaScript). The signature is then verified on Java back end. To verify the signature I am passing to the backend - (signature value, public key and message for verification). So far so good, but then the question arises - What if someone performs a man in the middle attack? He can easily generate a signature and send his - (signature value, public key and message.). So in a sense, this makes my current implementation not secure enough.
How can I avoid this? As far as I researched I have to verify that the public key sent is coming from the appropriate client and this is done through CA (Certificate Authority). However, in my case, I am doing this as a final project in university and I am not sure how to approach this problem.
Should I generate the public key certificate on the client side and send them along with the public key? Is it possible to generate self-signed-certificates on client-side and then verify it on the back-end?
What if someone performs a man in the middle attack
A MITM could replace the signature and the public key
How can I avoid this?
Mainly use SSL/TLS and/or...
As far as I researched I have to verify that the public key sent is coming from the appropriate client and this is done through CA (Certificate Authority)
If you use a Certificate Authority, each certificate is signed with the private key of the root CA certificate (or a subCA), so a MITM can not create a valid certificate because he does not own the root private key.
At server side, you can validate that the signature has been performed with a private key that corresponds to a certificate issued by the CA. Note that in this case you are working with certificates, not just with public keys ( a certificate envelopes a public key).
I am doing this as a final project in university and I am not sure how to approach this problem.
You have explained your solution but not the background. I mean why do you decided you need a digital signature? without that information I can not advise you.
Should I generate the public key certificate on the client side and send them along with the public key?
Read my previous comment
Is it possible to generate self-signed-certificates on client-side and then verify it on the back-end?
Yes, of course. You can generate a key pair at client side and associate the public key with the user's account during the registration process (using a secure channel)
This way you do not even need a password. The digital signature with the private key is the authentication proof. Using a CA is optional. The CA could issue a certificate containing the public key, but fot this scenario is not required

How to sign a message with my https public key certificate?

I just got myself an ssl certificate for my domain and it works fine, but I'm using the bitcoin payment protocol and I need to sign the messages with my public key before sending them but how are messages signed with an ssl certificate and what tools should I use?
EDIT
It seems what I actually need to do is sign a message using the public key of my ssl certificate issuer.
Thanks in advance :)
The protocol specification must be incorrect. Digital signatures are signed with your private key.
Your certificate needs to accompany the message, and probably be included in the signature. Use the java.security.Signature class in association with your private key, possibly loaded from your KeyStore.
You may need to purchase a signing certificate: an SSL certificate may not be strong enough for bitcoin.
A signature using a public key is completely worthless. Anyone can do it. You sign with your private key. This is legally equivalent to your signature: only you can do it, and anyone can check it by verifying it with your public key, which is why the public key must accompany the signature; and at the same time they can establish whose signature it is, via the certificate which must also accompany the signature.
Or else bitcoin is radically insecure.
Mystery solved, the message is to be signed using the bitcoin public key with the signmessage "bitcoinaddress" "message" bitcoin command.

Certificates, Encryption, And Authentication

Mostly, my confusion seems to be eminating from my attempts to understand security within the context of WCF. In WCF, it looks like certificates can be used for the purpose of authentication, as well as encryption. Basically, I am trying to understand:
How can an X509 certificate be used as an authentication token? Aren't ssl certificates usually made to be publically available? Wouldn't this make it impossible for them to be used for authentication purposes? If not, are there some protocols which are commonly used for this purpose?
When encrypting messages with WCF, are certificates used which have been issued only to the client, only to the server, or to both? If certificates from the client and server are both used, I'm a little unclear as to why. This mostly stems from my understanding of https, in which case only a certificate issued to the server (and chained to some certificate issued by a root CA) would be necessary to establish an encrypted connection and authenticate the server.
I'm not entirely sure this is the correct forum. My questions stemmed from trying to understand WCF, but I guess I would like to understand the theory behind this in general. If it's a good idea, please suggest the correct forum for me. I'd be happy to try to get this question migrated, if necessary.
Thanks in advance!
Well this is pretty complex question. I will try to explain some parts but avoiding as much detail as possible (even after that it will be pretty long).
How does authentication with certificate work?
If a holder of the private key signs some data, other participants can use the public key of the signer to validate the signature. This mechanism can be used for authentication. Private and public keys are stored in certificate where private key is kept safe on the holder machine whereas certificate with public key can be publicly available.
How does it relate to HTTPS?
WCF offers transport and message security. The difference between them is described here. The transport security in case of HTTP is HTTPS where only server needs issued certificate and client must to trust this certificate. This certificate is used both for authenticating server to the client and for establishing secure channel (which uses symmetric encryption).
HTTPS also offers variant called Mutual HTTPS where client must have also issued certificate and client uses the certificate to authenticate to the server.
How does message security work and what is a purpose of two certificates in that scenario?
In case of message security each message is signed, encrypted and authenticated separately = all these security informations are part of the message. In case of SOAP this is described by many specifications but generally you are interested in security bindings and X.509 Token profile.
Security binding is part of WS-SecurityPolicy assertions and it is describes how the message is secured. We have three bindings:
Symmetric security binding - symmetric encryption
Asymmetric security binding - asymmetric encryption
Transport security binding - assertion that message must be send over HTTPS or other secured transport
X.509 Token profile specifies how to transport certificates (public keys) in messages and how to use them.
Now if you have symmetric security binding you need only server certificate because
When client wants to send message to the server it will first generate random key.
It will use this key to encrypt and sign request
It will use service certificate to encrypt derived key and pass it to the request as well.
When the server receives the message it will first use its private key to decrypt that key.
It will use decrypted key to decrypt the rest of the message.
It will also use the key to encrypt the response because client knows that key.
Client will use the same key generated for request to decrypt the response
This is symmetric encryption which is much more faster then asymmetric encryption but key derivation should not be available in WS-Security 1.0. It is available in WS-Security 1.1. HTTPS internally works in similar way but the key is the same for the whole connection lifetime.
If you have asymmetric security binding you need two certificates:
Initiator must have its own certificate used to sign requests and decrypt responses
Recipient must have its own certificate used to decrypt requests and sign responses
That means following algorithm
Initiator encrypts request with recipient's public key
Initiator signs request with its private key
Recipient uses initiator's public key to validate request signature
Recipient uses its private key to decrypt request
Recipient uses initiator's public key to encrypt response
Recipient uses its private key to sign response
Initiator uses recipient's public key to validate response signature
Initiator uses its private key to decrypt response
The order of signing and encrypting can be changed - there is another WS-SecurityPolicy assertion which says what should be done first.
These were basics. It can be much more complex because message security actually allow you as many certificates as you want - you can for example use endorsing token to sign primary signature with another certificate etc.
The certificate only has the public key of a public/private key pair. It does not have the private key -- this is separate from the certificate proper. When you connect to an HTTPS server, you can trust that the server is the owner of that certificate because the server must be holding the private key (and hopefully nobody else has it) because otherwise the SSL connection is not possible. If the server did not hold the private key that pairs with the public key of its certificate, it could not present you with a valid SSL connection.
You then can decide whether or not you trust that particular certificate based on one or more certificate authorities (CA) that have signed the chain of certificates. For example, there may be just one CA that has signed this certificate. You have a trusted CA root certificate locally, and so you know that it in fact was your trusted CA that signed that server certificate, because that signature would not be possible unless that CA held the private key to the CA certificate. Once again it is merely holding the private key, in this case that proves who signed the certificate. This is how you can trust the certificate.
When you present the optional client certificate on the SSL connection, the server can trust you because 1) it can see the CA (or CA's) that sign your client certificate, and 2) it can tell that you have your private key in your possession because otherwise the SSL connection would not be possible. So it also works in reverse for the server trusting the client.
You can tell that everybody is honest if you trust that the server and client are keeping their private keys private, and if you trust the source of your root certificates that sign the server and client certificates (or chains of certificates.)

How does a ROOT CA verify a signature?

Say when using https, browser makes a request to the server and server returns its certificate including public key and the CA signature.
At this point, browser will ask its CA to verify if the given public key really belongs to the server or not?
How is this verification done by the Root cert on the browser?
To give an example:
Say serverX obtained a certificate from CA "rootCA". Browser has a copy of rootCA locally stored. When the browser pings serverX and it replies with its public key+signature. Now the root CA will use its private key to decrypt the signature and make sure it is really serverX?
is it how it works?
Your server creates a key pair, consisting of a private and a public key. The server never gives out the private key, of course, but everyone may obtain a copy of the public key. The public key is embedded within a certificate container format (X.509). This container consists of meta information related to the wrapped key, e.g. the IP address or domain name of a server, the owner of that server, an e-mail contact address, when the key was created, how long it is valid, for which purposes it may be used for, and many other possible values.
The whole container is signed by a trusted certificate authority (= CA). The CA also has a private/public key pair. You give them your certificate, they verify that the information in the container are correct (e.g. is the contact information correct, does that certificate really belong to that server) and finally sign it with their private key. The public key of the CA needs to be installed on the user system. Most well known CA certificates are included already in the default installation of your favorite OS or browser.
When now a user connects to your server, your server uses the private key to sign some random data, packs that signed data together with its certificate (= public key + meta information) and sends everything to the client. What can the client do with that information?
First of all, it can use the public key within the certificate it just got sent to verify the signed data. Since only the owner of the private key is able to sign the data correctly in such a way that the public key can correctly verify the signature, it will know that whoever signed this piece of data, this person is also owning the private key to the received public key.
But what stops a hacker from intercepting the packet, replacing the signed data with data he signed himself using a different certificate and also replace the certificate with his own one? The answer is simply nothing.
That's why after the signed data has been verified (or before it is verified) the client verifies that the received certificate has a valid CA signature. Using the already installed public CA key, it verifies that the received public key has been signed by a known and hopefully trusted CA. A certificate that is not signed is not trusted by default. The user has to explicitly trust that certificate in his browser.
Finally it checks the information within the certificate itself. Does the IP address or domain name really match the IP address or domain name of the server the client is currently talking to? If not, something is fishy!
People may wonder: What stops a hacker from just creating his own key pair and just putting your domain name or IP address into his certificate and then have it signed by a CA? Easy answer: If he does that, no CA will sign his certificate. To get a CA signature, you must prove that you are really the owner of this IP address or domain name. The hacker is not the owner, thus he cannot prove that and thus he won't get a signature.
But what if the hacker registers his own domain, creates a certificate for that, and have that signed by a CA? This works, he will get it CA signed, it's his domain after all. However, he cannot use it for hacking your connection. If he uses this certificate, the browser will immediately see that the signed public key is for domain example.net, but it is currently talking to example.com, not the same domain, thus something is wrong again.
The server certificate is signed with the private key of the CA. The browser uses the public key of the CA to verify the signature. There is no direct communication between browser and CA.
The important point is that the browser ships with the public CA key. So the browser knows beforehand all CAs it can trust.
If you don't understand this, look up the basics of Asymmetric Cryptography and Digital Signatures.
Certs are based on using an asymmetric encryption like RSA. You have two keys, conventionally called the private and public keys. Something you encrypt with the private key can only be decrypted using the public key. (And, actually, vice versa.)
You can think of the cert as being like a passport or drivers license: it's a credential that says "this is who I am; you can trust it because it was given to me by someone (like Verisign) you trust." This is done with a "signature", which can be computed using the certificate authority's public key. If the data is what the CA got originally, you can verify the cert.
The cert contains identifying information about the owner of the cert. When you receive it, you use the combination of the key you know from your trusted authority to confirm that the certificate you received is valid, and that you can therefore infer you trust the person who issued the cert.
Your browser does not ask the CA to verify, instead it has a copy of the root certs locally stored, and it will use standard cryptographic procedure to verify that the cert really is valid.
This is why when you self sign a certificate your certificate is not valid, eventhough there technically is a CA to ask, you could off course copy the self signed CA to your computer and from then on it would trust your self signed certifications.
CACert.org has this same issue, it has valid certificates but since browsers don't have its root certs in their list their certificates generate warnings until the users download the root CA's and add them to their browser.