The principle of public-key cryptography is fairly simple to get.
- Alice has a public/private keypair.
- Alice gives the public key to Bob.
- Bob encrypts some data for Alice using the public key.
- Bob sends the data to Alice, who can decrypt it using her private key.
There’s also some other stuff about multiplying large primes, and how difficult it is to reverse that. But how on earth does this relate to certificates in the real world? If you click on that padlock in your browser, how does that relate to the above scenario?
For this demonstration, let’s use OpenSSL, as it’s commonly available. I’m going to make a “self-signed” key pair. More on that in a moment.
% openssl req -out cert -newkey rsa:2048 -keyout key -x509 Generating a 2048 bit RSA private key ......................+++ .............+++ writing new private key to 'key' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:GB State or Province Name (full name) [Some-State]:. Locality Name (eg, city) :Brighton Organization Name (eg, company) [Internet Widgits Pty Ltd]:happygiraffe Organizational Unit Name (eg, section) :. Common Name (eg, YOUR name) :Dominic Mitchell Email Address :email@example.com hdm-macbookpro% ls -l total 16 -rw-r--r-- 1 hdm 5000 1554 19 Mar 17:51 cert -rw-r--r-- 1 hdm 5000 1751 19 Mar 17:51 key
So, what do we have here? Let’s look at the key first.
% openssl rsa -in key -noout -text Enter pass phrase for key: Private-Key: (2048 bit) modulus: 00:b4:73:f1:5d:53:e1:ca:e9:9b:5a:02:14:7d:d4: … publicExponent: 65537 (0x10001) privateExponent: 00:8a:77:e1:81:1c:e9:c9:1b:a2:f2:d9:5f:c2:02: … prime1: 00:dd:cc:63:f6:08:0d:dc:18:ca:73:1a:04:17:7c: … prime2: 00:d0:47:6a:b7:9a:35:1c:5f:a6:a5:46:f0:ec:3e: … exponent1: 57:76:08:98:f5:16:1a:0b:80:91:a0:d9:aa:35:25: … exponent2: 07:60:50:1e:3a:7e:e1:07:5e:2e:82:49:ac:04:36: … coefficient: 00:8b:79:fb:33:d1:e6:08:f0:e9:ac:ef:8c:9c:0e: …
Hmmm, lots of maths stuff. What’s in the certificate?
% openssl x509 -in cert -noout -text Certificate: Data: Version: 3 (0x2) Serial Number: f4:00:d8:ff:2b:10:b4:fe Signature Algorithm: md5WithRSAEncryption Issuer: C=GB, L=Brighton, O=happygiraffe, CN=Dominic Mitchell/emailAddressfirstname.lastname@example.org Validity Not Before: Mar 19 17:51:38 2010 GMT Not After : Apr 18 17:51:38 2010 GMT Subject: C=GB, L=Brighton, O=happygiraffe, CN=Dominic Mitchell/emailAddressemail@example.com Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (2048 bit) Modulus (2048 bit): 00:b4:73:f1:5d:53:e1:ca:e9:9b:5a:02:14:7d:d4: … 09:3b Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 56:F8:A1:FC:C0:B0:D3:5A:74:A2:2B:BC:91:1D:67:B1:84:42:88:B8 X509v3 Authority Key Identifier: keyid:56:F8:A1:FC:C0:B0:D3:5A:74:A2:2B:BC:91:1D:67:B1:84:42:88:B8 DirName:/C=GB/L=Brighton/O=happygiraffe/CN=Dominic Mitchell/emailAddressfirstname.lastname@example.org serial:F4:00:D8:FF:2B:10:B4:FE X509v3 Basic Constraints: CA:TRUE Signature Algorithm: md5WithRSAEncryption ae:82:88:3b:0b:85:4b:0f:6d:54:b0:27:ac:d1:ec:4c:b1:70: … dc:e5:26:d5
There’s a great deal of useful information here. Note that “Issuer” and “Subject” fields are identical. This is what I meant by “self-signed” earlier. For a purchased certificate, the issuer would be somebody like Verisign or Thawte. Also for a certificate that’s being used for an SSL server, the CN field in the subject would have to match the hostname of the site it’s serving.
In the middle, under “Subject Public Key Info” there is some of the same information that’s present in the key (Modulus and Exponent). But there’s a lot that isn’t (this is good — you want to keep the private key private).
What’s that signature? Well, it’s a way of ensuring that the contents of the certificate can’t be tampered with. Otherwise, somebody could just alter the Subject Public Key Info to point to a different key that they control. It assures the integrity of the certificate. Think of it like a secure wrapper.
So, we’ve got a certificate with public key information inside, but how is actually used in practice? OpenSSL will let us simulate a client and a server. Open up a terminal window and run:
% openssl s_server -cert cert -key key -msg Using default temp DH parameters Enter PEM pass phrase: ACCEPT
Open another command line and run:
% openssl s_client -debug -connect localhost:4433 -msg CONNECTED(00000004) … >>> SSL 2.0 [length 0074], CLIENT-HELLO … <<< TLS 1.0 Handshake [length 004a], ServerHello … <<< TLS 1.0 Handshake [length 045c], Certificate … depth=0 /C=GB/L=Brighton/O=happygiraffe/CN=Dominic Mitchell/emailAddressemail@example.com verify error:num=18:self signed certificate verify return:1 depth=0 /C=GB/L=Brighton/O=happygiraffe/CN=Dominic Mitchell/emailAddressfirstname.lastname@example.org verify return:1 … <<< TLS 1.0 Handshake [length 018d], ServerKeyExchange … <<>> TLS 1.0 Handshake [length 0046], ClientKeyExchange … >>> TLS 1.0 ChangeCipherSpec [length 0001] … >>> TLS 1.0 Handshake [length 0010], Finished … <<< TLS 1.0 ChangeCipherSpec [length 0001] … <<< TLS 1.0 Handshake [length 0010], Finished --- Certificate chain 0 s:/C=GB/L=Brighton/O=happygiraffe/CN=Dominic Mitchell/emailAddressemail@example.com i:/C=GB/L=Brighton/O=happygiraffe/CN=Dominic Mitchell/emailAddressfirstname.lastname@example.org --- Server certificate -----BEGIN CERTIFICATE----- … -----END CERTIFICATE----- subject=/C=GB/L=Brighton/O=happygiraffe/CN=Dominic Mitchell/emailAddressemail@example.com issuer=/C=GB/L=Brighton/O=happygiraffe/CN=Dominic Mitchell/emailAddressfirstname.lastname@example.org --- No client certificate CA names sent --- SSL handshake has read 1670 bytes and written 252 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA Server public key is 2048 bit SSL-Session: Protocol : TLSv1 Cipher : DHE-RSA-AES256-SHA Session-ID: 422BC3AE9F6B11C32770C6A6DB8B915713754C00694FCCF6BA37FE14A3D5C087 Session-ID-ctx: Master-Key: 32895E90044DFE72B8CAEC4B7D4E14DF9969109AFE9F0504C69CA4B9CB9259E177C85B498F9F850EBF5866DF47A45B17 Key-Arg : None Start Time: 1269245236 Timeout : 300 (sec) Verify return code: 18 (self signed certificate) ---
This is really verbose (it is a debugging tool), so I’ve removed much of the output. But it shows the important steps in the SSL transaction. Of particular interest is the line near the end stating the Master-Key. This reveals the truth behind public key crypto: it’s expensive enough that it’s used for just long enough to exchange a regular two-way encryption key between the two peers. The public key information in the certificate is only used to encrypt a single message to the server (ClientKeyExchange) containing the private key to use for this session.
Of course, there’s a lot more to SSL connections than this. I’ve obtained most of this from SSL & TLS Essentials, which has a very detailed breakdown of precisely what’s happening.
Please don’t rely on the above in any way — it’s just my interpretation. But it does seem useful to explore certificates a little bit more.