On a high level, it seems to me that SSL has two distinct functions:
To bind a domain name to a specific organization
To send out a public key for encryption
These functions seem very different to me. What is missing from my understanding of the model?
Update for clarity: I base my question on findings from searches. For example, one source says, “SSL Certificates bind together: A domain name, server name or hostname. An organizational identity (i.e. company name) and location.” And, other sources discuss encryption.
SSL has none of the functions to describe. What you describe are only parts of how the actual functionality is achieved. The real function of SSL is to protect the data in transit.
The certificate with subject and key is needed within this function (at least) to authenticate the server in order to make sure that the client talks to the expected server and not to some man in the middle. This is achieved by making sure that a) the certificate is issued by a trusted party (the certificate authority) and that it is issued to the expected domain, i.e. the same one which is included in the visited URL.
Note that SSL does not make any claims about how trustworthy the site or the party behind the certificate is. It also does not make any claims if the organization you expect is really the one which owns the visited domain. The latter part is done by the certificate authority for some kind of certificates, i.e. the EV certificates. But for most certificates it is only checked that the current owner of the domain requested the certificate and not who the owner actually is.
Related
According to my understanding, when we are trying to connect to a website/url, even if one of the certificates in the SSL certificate chain of the website is present in the trust store then connection is established successfully. But, I want to establish a connection only if the domain level certificate is present in the trust store. And I am not allowed create a new trust store instead need to use the default trust store. How can this be implemented in Java? TIA.
Unfortunately for you, that's not how PKIs were designed to work. The search for any trusted root certificate in the chain is a design feature of PKIs that ensures we don't have to install a certificate per domain on clients - bloating local trust stores with millions of certificates and complicating revocation and renewal of certificates.
What you're looking for is referred to certificate pinning where the client validates that the certificate presented by the server has a specific thumbprint it knows and trusts before continuing any further communication with the server on the other end. It is essentially the client authenticating the server.
Depending on your particular implementation, the validation logic can be done in the application instead of at the TLS/SSL protocol layer, meaning you can do as much (CN, Key Usage Attributes, SAN) or as little (just thumbprint)validation as you want , but typically certificate thumbprints are used since they are *guaranteed to be unique. A interception proxy or other man-in-the-middle for instance can create a certificate with valid CN entry for your domain (valid domain validation), but they cannot spoof the thumbprint.
A certificate is a unique token issued to a particular individual. It is a form of identification, similar to a government-issued photo ID which most people carry.
Certificates were designed for one purpose - to convey an identity which can be verified as authentic. It does this via a chain of trust. If a client or server trusts the issuer of a certificate, then it will automatically trust the certificate.
Put in similar terms, this is similar to the TSA specifying guidelines for which forms of identification it will accept before it will let you into the security checkpoint. As long as you possess one of those valid forms of ID, the TSA will let you through. This is how the PKI is designed, and it has to be designed that way to function efficiently. So, there is no way to do this explicitly in the PKI framework.
What you're instead asking for is a separate level of identify verification beyond what PKI provides. A possible solution could be certificate pinning, but I'm not sure this gets you anywhere. If the private key is compromised, which is probably more likely than compromising a trusted CA, then you haven't gained any additional level of security.
Instead, best practice is to implement multi-factor authentication. Using the certificate itself as a second factor really doesn't make a whole lot of sense, because it isn't truly a two-factor identity. Instead, it would make more sense to use the PKI as-is, and establish a second authentication mechanism via TOTP or some other independent token generation.
Reading up on SSL certificates. There is plenty of material on verifying certificates, CA roots, etc. However, if I want to be certain that only a given
group of servers can be accessed, is there anything wrong with just keeping a cache of the Base64/pem format certs in a file and comparing them?
I have seen answers on the web that the cert will change according to when it was accessed, so I got the pem on an example server, www.yahoo.com, then stored it, accessed the same server and got another pem later, and they matched. I suspect that the cert will be as good as a fingerprint until expiration or the server changes to a new cert.
My idea is to show the decoded cert to the user, then store the base64 verion in a file/cache to form a list of "very trusted servers", or alternately let the user simply form his/her own list of such servers.
The other answer I have seen is to store and compare the decoded version, but this does not seem to me to be as secure as directly comparing the encoded cert.
Thanks for opinions.
If the certificates are validated during the handshake according your requirements, then you may use such a whitelist.
Using "trust-management" is in my opinion not more complex than such a whitelist. Especially, of all peers are controlled by the same organisation. You can create your own CA (even a offlineCA, may be you setup a organisation specific process to ensure, that the CA's private key is used compliant), and as good as you protect that CA's private key, you may trust that CA. So simply use that CA certificate as "only" trust to your TLS/DTLS setups on client and server, and sign all client and server certificates with that CA.
When I open the SSL details of an internal application inside network (Intranet enterprise application) - I see 3 levels of certificates? What does each level mean?
There is no specific definition of each "level".
The HTTPS world works using a PKIX model: each entity (here specifically website and their hostname) is authenticated by some X.509 certificate.
For the trust to happen this server certificate needs to be signed by another certificate, called an authority certificate that you trust.
Browsers are shipped with hundreds of default authority certificates. The system is built under the assumption that you trust the entities behind those certificates fully (yes, without having at any point seen all this list or explicitely given consent; you can remove all of them from your browser's or even OS trust store but then you will not be able anymore to connect anywhere through HTTPS and you will need to re-add them one by one), which means you accept as valid (besides other technical checks like on dates, etc.) any certificate signed by these authority certificates.
But for multiple technical and non technical reasons, authorities often do not sign end certificates directly but uses intermediary certificates (the "middle" level in your case if you want).
It does not change anything from the model above as the trust flows from the root and when you connect to a server it is responding with its own certificate plus any other intermediaries needed to reach back any trusted root.
Note that the depth may vary. Some authorities may issue end certificate directly (so you will have 2 "levels" in the output), some may use one intermediary (frequent case), some may use a cascade of intermediaries (intermediaries through some technical points in their certificate can be restricted to sign only some specific certificates like under specific names and so on), this is all up the certificate authority that issued the given end certificate you are looking at.
And when you deal with "self-signed" certificates, you do not have levels anymore because the certificate is signed by itself which means it is its own certificate authority, so it is alone in the list of certificates.
If you create a certificate signing request and include the identifying information (e.g. Distinguished Name, Business name, Town/City, e-mail address), is any of this data included in the certificate itself (which the CA issues to you based on the CSR)?
Or is it simply used by the certificate authority to identify you before agreeing to sign the public key?
For a more full list of identifying information see the table at https://en.wikipedia.org/wiki/Certificate_signing_request
It depends on CA configuration and request generation code. For example, when working with Microsoft Enterprise CA public key and certificate template name is sufficient. CA server will look into certificate template properties (including subject name) to construct certificate. When working with Microsoft Standalone CA, all required extensions, subject field must be provided explicitly in the request.
Commercial CAs may require different set of information to construct the certificate.
It is about CA requirements. Request generation code may put additional information which may (not necessary) be used by CA to construct certificate. For example, certreq.exe or CertEnroll COM interfaces include request originator information: user account name, host name, process name and default extensions (KeyUsage) based on key settings (AT_EXCHANGE or AT_SIGNATURE).
In other word, there is no definite answer to this question. Everything depends on client and server software. Different client software may include different information.
It depends on the CA, but a good CA should not copy what you've put in your CSR blindly.
When a CA issues a certificate, it effectively vouches for the identity information and attributes it puts in the certificate. Therefore, it shouldn't put data such as organisation name, location, e-mail address unless it has been able to verify them externally. It's a good thing from a security point of view in principle, and since they generally make you pay extra for additional attributes, it's also in their commercial interest not to let you choose what goes in.
In practice, it depends on the type of certificate you go for (e.g. domain-validated, EV certificate, ...). The extra pieces of informations will generally be verified by the CA through some administrative process, so what's in the CSR itself is barely relevant, since they'll construct the CA based on whatever information they will be willing to assert.
For example, for domain-validated certificates, some CAs will construct a DN like OU=Domain Validated, CN=your.host.name, irrespectively of the DN you've actually put in the CSR. They might even throw in a couple of Subject Alternative Names, with and without the www. prefix automatically.
I have a distributed application consisting of many components that communicate over TCP (for examle JMS) and HTTP. All components run on internal hardware, with internal IP addresses, and are not accessible to the public.
I want to make the communication secure using SSL. Does it make sense to purchase signed certificates from a well-known certificate authority? Or should I just use self-signed certs?
My understanding of the advantage of trusted certs is that the authority is an entity that can be trusted by the general public - but that is only an issue when the general public needs to be sure that the entity at a particular domain is who they say they are.
Therefore, in my case, where the same organization is responsible for the components at both ends of the communication, and everything in between, a publicly trusted authority would be pointless. In other words, if I generate and sign a certificate for my own server, I know that it's trustworthy. And no one from outside the organization will ever be asked to trust this certificate. That is my reasoning - am I correct, or is there some potential advantage to using certs from a known authority?
There is no need for you to use an external public CA for a closed community project. In many larger organisations they operate an internal PKI to issue certs for internal projects like this. An advantage of using a PKI is that you can setup a trust relationship between the various components based on a single securely distributed root certificate / trust anchor.
However, if the project allowed internal users to connect securely to an internal service via their web browser you may want to consider using a public CA issued cert. The alternative is to make sure that every browser that may need to connect to your service trusted your root cert; this is to prevent browser warning messages.
I'd say it's reasonably safe, unless you think a ninja infiltrator is going to swap your server on you.
The 3rd party is there to make it harder to just 'up & generate' a new cert. Someone could re-create a self-signed cert on a new machine with the same details, it wouldn't be the same cert, you'd have to add an exception for it too, but your users probably wouldn't know the difference.
As long as your system is running inside your group and there are no plans to expand it (and plans do change, so keep that in mind), it is just fine to setup your own simple PKI infrastructure.
If you do end up expanding beyond your organization, all you need to do is distribute your root certificate to the parties you will be communicating. This gives actually a fine grained control to your partners how much trust they want to put in you vs the public CA infrastructure.