I'm building a web service and have questions regarding authentication. I have a strict requirement that this application only run on company machines. We have a root certificate this is installed on all the machines in the company. I'm planning to use this certificate for authentication. My idea is - when the client runs on any machine, it fetches this root certificate and sends it to the server. The server only continues processing the request after successful validation. What validations should I perform? Subject name? Thumbprint? Given that it is a root cert, the subject name and issuer are same. How can I ensure this certificate comes from a trusted authority? Also, is this a good approach for authentication? I'm new to this area and looking for any help I can get.
We have a root certificate this is installed on all the machines in the company.
The purpose of this certificate is that every user of your company can validate your servers. For instance, some user to your server. Browser attempts to establish a TLS connection. For this purpose server presents a certificate. This certificate is signed by your internal CA. Browser retrieves a certificate from your server and checks who has issued it. Browser finds in the local registry a root certificate of your company, verifies that certificate presented by the server is really signed by the root certificate, verifies some other attributes (e.g. that the name in server certificate corresponds to DNS name), and then browser of this users trusts the server, and TLS connection will be installed.
I'm planning to use this certificate for authentication.
Presenting root CA certificate of your company does not mean anything. It is not secret. It is public information. It can be freely copied. Anyone can present root certificate of CAs of your departments.
If you want to authenticate users based on certificates and your root CA certificate, you should do following:
- Issue a certificate for every user. Sign this certificate with root CA certificate of one of your departments.
- Every user should install his certificate on his computer.
- Configure your server so that it knows root CA certificates of your departments.
- Configure your server so that it requires certificate based authentication from clients.
How it works?
The authentication will look then as follows:
- User wants to call some service. Browser on his computer sends a request to the server.
- Server presents its certificate. Browser verifies it and trusts it.
- Server asks browser to authenticate itself using certificate.
- Browser uses a client certificate belonging to the particular user logged on this computer.
- Server checks if this certificate is valid. On of validations is to check that this user certificate was issued by CA whom the server can trust. Server finds the root CA of the issuer of client certificate in its registry, verifies signature in the user certificate, and trusts this user certificate.
- Since certificates are public and don't prove anything, browser signs data sent to server using the private key related to this certificate and available on users computer. The private key is secret, every user has his own private key and own certificate.
- Server checks if the signature of the data received from browser does really match the certificate presented by browser. If matches, it means that the user is really the owner of the presented user certificate. Thus the user is authenticated.
This is a simplified description. In reality validation is a bit more complex: User certificates must have valid dates, they must have particular values of some attributes, e.g. for what purposes is this certificate allowed to be used.
Briefly, to make it work you need to do steps 1 - 4 above.
Important: You don't need to implement anything to get authentication based on certificates. You just need to configure your web server (Apache, Nginx, whatever) correspondingly. If you use a typical approach when a web server receives all requests and forwards application related requests to the application, then in the application you will know: If some requests has reached the application, user is authenticated based on certificate.
Use TLS you don't need to do anything else. Don't try to build your own protocol unless you have someone very good at cryptography, even then it is not worth the risk. The server, not the client sends the entire certificate chain including the root. All of your machines will have this root installed and thus accept it. Otherwise abort the connection. At most you may have to rewrite client so that it only accepts your company root as a trusted root.
EDIT: Digital certificates by themselves do not authenticate anyone. They are never meant to be secret in the first place. It's purpose is to certify that the public key of some server or anything indeed belongs to it. Your certificate contains your public key which is used to verify your signatures. The public key is used to verify that the signature used authenticate the server (and client if it is two-way) is indeed valid. The signature is also used to ensure that key exchange has not been tampered with. After key exchange, the data communicated is secured by encrypting (which also includes message authentication with it) it. If you just send your public key bare instead of the certificate, an attacker can easily inject her own public key instead making it insecure. The signature in question can only be produced using a private key which is paired with that public key. I won't go into much detail you can look into mathematics of cryptography if you are interested but deriving private key from the public key is infeasible, at least we know of no easy way to calculate private key from public key.
Significance of Root Certificate
I believe you're misunderstanding the significance of having the Root certificate installed on company computers. This certificate is the public key of the Root Certificate Authority (CA) for the company's certificate infrastructure and its presence doesn't necessarily indicate a system is a company computer. The Root certificate should be freely available so anyone can download it and install it as a trusted certificate. Doing so indicates the system will trust the certificate infrastructure the Root certificate is the parent of. Thus trusting any certificate issued by the certificate infrastructure. Examples of issued certificates include SSL/TLS, S/MIME, etc.
Authentication with certificates requires one to have the associated private key. For example, HTTPS (e.g. SSL/TLS) authentication works because the webserver has the corresponding private key. The public key can be shared with anyone. The private key is what allows one to know they are communicating with the correct endpoint. The SSL/TLS negotiation process ensures this. Which is why the private key must remain private.
Requirement: Run on Company Computers Only
With strict requirements to only allow your application to run on company systems, I can think of two options:
1. Leverage Existing Certificate Infrastructure
Issuing Client Certificates is the best approach if you desire to leverage your existing certificate infrastructure. Doing so requires each company computer to be issued their own computer certificate from your Root CA or more likely Issuing CA. Each system will then have a public and private key from the newly issued computer certificate. Having your application verify a system has been issued this certificate would indicate a company system. Presenting this certificate during authentication would be the best approach.
There are downsides:
- There must be an established certificate lifecycle. Define characteristics of what a company computer is and properties of the computer certificate. How long should a certificate be valid, how will certificates be revoked, Extended Key Usage, etc. Then establish how a computer requests and receives a certificate. All of this requires changes to the Issuing CA (Root or otherwise) and Policy CA (if present).
- Managing computer certificates must be automated. Company computers must be issued new certificates and expiring certificates need to be renewed behind the scenes. This should happen automatically and without intervention by users.
- Users are accustomed to authenticating via username/password credentials. Using certificates is different and based on implementation it may produce a process undesired by users.
2. Restrict Access to Company Network
Since your application is hosted in the cloud, setup a VPN between the internal company network and your application. Thereby only making the application accessible via your internal network. This should satisfy the requirement since in theory only company computers should be connected to the internal company network. Check with the policymakers within the organization to be sure.
Based on your question and various comments, I'd recommend using this approach.