Does a Certificate Authority See Your Private Key?

One of the questions I had for a long time now is if a Certificate Authority sees the private key of an SSL certificate for a web server during the certification process? If so, it would be quite a security issue.

Before answering the question, it's probably a good idea to quickly have a look at what an SSL certificate and a certificate authority is and what they are needed for:

The first purpose of an SSL certificate is for it to be sent from a web server to a web browser whenever the https (http secure) protocol is used to establish an encrypted connection. The SSL certificate contains the public key of the web server that is used to generate a session encryption key. The basic idea behind this approach is that anything that is encrypted with the public key can only be decrypted again with a private key that only the web server knows, i.e. it is never transmitted to the web browser. In other words an attacker that eavesdrops on the communication can't use the private key to decrypt the packets he sees passing through.

The second purpose of an SSL certificate is to contain information for the web browser so that he can validate that the connection is really established to the web site the user wants to visit and is not to a malicious other site to which he was redirected by a potential attacker. To achieve this, an SSL certificate has to be signed by a Certificate Authority that vouches for the validity of the certificate. Signing a certificate is done once and requires that the person or company requesting validation from a Certificate Authority can prove that it is the owner of the domain name in the certificate. This are several ways to do this and I'll describe that in a separate blog post. Once the Certificate Authority has established that the person or company requesting the certificate is the rightful owner of the domain name it generates a public certificate from the information supplied by the requester in a certificate signing request (CSR) which contains, among other things, the domain name (e.g. www.wirelessmoves.com) and the public key to be used.

The important point is that the Certificate Authority does not generate any keys, it just uses the information supplied by the person or company contained in the certificate signing request, signs that with its own key and returns the result. And here's the crucial point: Does the information that is sent to the Certificate Authority also contain the private key that is later on used on the web server side? Would that be the case then the certificate authority would have information that, when obtained legally or illegally, would allow decrypting intercepted data packets.

To answer this question I recently tried it out myself when I needed to get an SSL certificate for my home cloud. And here's how that works: On my server at home I generate a certificate signing request with the following Unix command:

openssl req -new -newkey rsa:2048 -nodes -keyout m-server.key -out server.csr

Before the command generates an output it requests additional information from the user such as the domain name (e.g. www.wirelessmoves.com), company name, location and so on. Once this information is given, the command generates two files : The .csr file which is the signing request and the .key file which is the private key. The next step is to select a certificate authority, which I will again describe in a separate post, and then copy/paste the content of the .csr file into a text box on the web page during the validation process. The public key in the .key file, however, NEVER leaves the server.

And just to make really sure that the private key is not part of the .csr file sent to the Certificate Authority, one can decode the contents of the signing request as follows:

openssl req -in m-server.csr -noout -text

This results in the following output:

Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=DE, ST=Ger, L=Cologne, O=wlx, CN=www.m-test.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:a5:5b:b8:8c:11:2e:cc:48:f9:a6:4c:ed:e6:52:
                    08:58:77:3c:44:a4:78:9f:7c:51:75:79:07:f4:7b:
                    […]
                    0a:4b:1f:bf:b9:90:7d:f8:72:01:50:bc:62:47:8d:
                    be:2e:9e:71:e9:0c:80:56:77:7d:27:05:1b:da:3d:
                    87:d9
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha1WithRSAEncryption
         73:7c:76:fa:74:b2:34:be:c1:36:9b:aa:06:51:25:e9:f9:df:
         43:0c:9a:a9:75:28:8e:5f:41:f0:30:da:7b:aa:29:90:ea:39:
         […]
         3e:63:d9:1c:e7:65:24:32:c6:05:da:47:10:fd:e9:00:29:ed:
         76:54:54:27:c6:ff:f4:e3:c5:e8:74:1c:dd:29:d0:18:b2:09:
         bd:4c:23:86

There we go, so here's the proof that the Certificate Authority never sees the private key and hence your communication is save from eavesdropping except from those that can steal the Certificate Authority's signature key or can set up a Certificate Authority trusted by web browsers (which I am sure quite a number of three letter agencies have already done) and stage a man in the middle attack. There are ways to protect yourself against that as well, e.g. by using the Certificate Patrol Firefox plugin. But that's another story I've already blogged about here.