I'm going to
spend a little time talking
about the SSLv3 handshake
using RSA for key exchange.
SSL allows two parties (the
client and the server) to
communicate using
encryption. Encryption
provides confidentiality,
meaning the conversation
between both parties is
private. The purpose of the
SSL handshake is to
authenticate one or both
parties of the connection
and to negotiate which
encryption algorithm and
keys to use.
SSL is not an encryption
algorithm. SSL is a protocol
that allows two parties to
negotiate which algorithm
and keys to use. The key in
an SSL session is generated
during the handshake and is
known as the "session key".
The session key is (with a
few exceptions) used only
for the session it was
created in.
The steps to the handshake
are:
ClientHello (C -> S)
ServerHello (C <- S)
Certificate ( C <- S)
CertificateRequest* (C
<- S)
ServerHelloDone (C <- S)
Certificate* (C -> S)
ClientKeyExchange (C ->
S)
CertificateVerify* (C ->
S)
ChangeCipherSpec (C ->
S)
Finished (C -> S)
ChangeCipherSpec (C <-
S)
Finished (C <- S)
*Optional step
I've
included some optional steps
in the figure above. These
steps are taken when
client-side authentication
is performed. Normally, only
the server proves its
identity during the
handshake. "Client-side
authentication" means the
client will also prove its
identity during the
handshake. Client-side
authentication is not
normally done when the
average user is using HTTPS
(HTTP over SSL), but is more
common with SSL connections
between businesses.
Enough of that, let's move
on to the actual parts of
the handshake.
ClientHello (C -> S)
The handshake begins with a
message from the client to
the server called "ClientHello".
The ClientHello contains
basic information indicating
what the client is capable
of. This message contains
the client version, a random
value, a session ID, a list
of cipher suites, and a list
of compression methods.
The client version indicates
the highest version of SSL
the client can support. It
is assumed the client is
backwards compatible. A
client using SSL version 3
can also support version 2
(which the server can
negotiate down to if it
chooses to).
The random value, known as a
"nonce", serves two
purposes. The nonce is one
of the variables used in
generating the session key
(discussed below), and also
prevents replay attacks
(also discussed later in the
"Finished" message).
The session ID can be used
to indicate the client wants
to resume a previously
negotiated session. The
advantage to this is time is
saved by not negotiating a
new session key. Usually,
the client will send a
session ID of zero to
indicate a new session must
be negotiated.
The cipher suites are a list
of encryption algorithms the
client supports, such as RSA
with 3DES or RSA with IDEA.
The client provides a
complete list of the ciphers
it is able/willing to
support so that the server
may choose one.
The list of compression
algorithms is meant to
function much like the list
of cipher suites: the client
provides a list of what it
can do and the server is
meant to pick one. In
reality, there are no
compression algorithms
officially defined for SSL,
so the only valid value here
is NULL. Some
implementations of SSL
support various compression
methods, even though none
have officially been
defined.
ServerHello (C <- S)
The ServerHello message
basically indicates which of
the client options the
server has chosen. The
ServerHello message has
version information, a
nonce, a session ID, a
cipher suite, and a
compression method.
The version number is the
version of SSL the server
will support for this
connection.
The nonce is a random value
generated by the server that
is used in the same fashion
as the client's nonce.
The session ID, cipher
suite, and compression
method are all values chosen
by the server, imposed onto
the client. The client sent
the values it can support,
and the server makes the
decision. If the server is
not willing to support the
client for whatever reason,
the server aborts the
handshake and closes the
connection. For example,
this can happen if the
server considers none of the
client's cipher suites to be
secure.
Certificate
(C <- S)
The server then sends a copy
of its
digital certificate to
the client. In some cases,
the server will also send
the certificate of the
issuer (for example, in the
case of intermediate CAs).
This is the first step in
proving the server's
identity.
CertificateRequest (C
<- S) (optional)
Optionally, the server can
request the client's
certificate. This message is
issued when the server wants
to verify the identity of
the client.
ServerHelloDone (C <-
S)
The server sends this
message to the client to
indicate it is done sending
messages at this point.
After the client has
received the server's
certificate (or certificate
chain), it will take a few
steps to validate the
certificate. The client will
check the subject name on
the certificate and compare
it to the domain name used
to connect to the server. If
the names do not match, the
client will abort the
handshake*.
The client checks the valid
dates on the certificate to
make sure the certificate is
not expired or is not being
used before it was allegedly
issued. The client also
attempts to validate the
digital signature on the
server's certificate,
assuming it trusts the
issuer. That is, if the
server sent a VeriSign
certificate, the client
would have to trust VeriSign
before the client accepted
the certificate. If the
client cannot validate the
certificate, the client will
abort the handshake*.
*Well, sometimes. On many
popular web browsers, the
user is prompted to make a
decision on whether to
continue with the handshake
or abort it.
Certificate (C -> S)
(optional)
If requested by the server
(with the CertificateRequest
message), the client will
send its own certificate at
this point.
ClientKeyExchange (C
-> S)
The client uses the nonce
values from the ClientHello
and ServerHello messages
and, using additional
sources of entropy, creates
the PreMasterSecret. The
PreMasterSecret is the value
that the client and server
will use to derive the
session key.
The integrity and
confidentiality of the
PreMasterSecret is
important. For these
reasons, the client encrypts
the PreMasterSecret with the
public key in the server's
certificate, and sends it to
the server as part of the
ClientKeyExchange message.
As long as the server is the
legitimate owner of the
certificate, it will have
the private key necessary to
decrypt the PreMasterSecret.
If the server is actually an
attacker posing as the owner
of the certificate, it will
be unable to decrypt the
PreMasterSecret, which means
it will be unable to derive
the session key. Without the
session key, the server is
unable to complete the
handshake (see the Finished
message).
CertificateVerify
(C -> S) (optional)
If the server requested the
client's certificate with
the CertificateRequest
message, the client needs to
prove it has the private key
that corresponds to the
public key in the
certificate it sent to the
server. The client
accomplishes this by
digitally signing the
handshake messages up this
point (using the client's
private key) and sends the
result to the server.
The server attempts to
validate the
digital signature using
the public key in the
certificate provided by the
client. If the signature
fails validation, the server
aborts the handshake and
closes the connection.
ChangeCipherSpec (C
-> S)
The client sends the
ChangeCipherSpec message to
the server to indicate it is
switching to the negotiated
encryption algorithm. Every
message the client sends
during the session from this
point on is encrypted with
the session key.
Finished (C -> S)
The client sends the
Finished message to the
server to indicate it is
finished with the handshake.
This message is encrypted
with the session key, and
contains a digital signature
of the session key and the
handshake messages up to
this point.
The nonce values sent in the
ClientHello and ServerHello
messages help to ensure that
the handshake messages from
different SSL sessions are
different, even if the
sessions are between the
same client and server.
Without the nonce values, it
may be possible under
certain circumstances for an
attacker to capture the
handshake messages between
the client and server and
replay them later in an
attempt to spoof one side.
ChangeCipherSpec (C
<- S)
The server sends the
ChangeCipherSpec message to
the client to indicate it is
switching to the negotiated
encryption algorithm. All
messages from the server
(during this session) will
be encrypted with the
session key from this point
on.
Finished (C <- S)
The server concludes the
handshake by sending the
Finished message, which is
encrypted with the session
key. This message contains
the digital signature of the
session key and all
handshake messages in this
session.