8.18 Using Diffie-Hellman and DSA Together
8.18.1 Problem
You want to use Diffie-Hellman for key
exchange, and you need some secure way to authenticate the key
agreement to protect against a
man-in-the-middle attack.
8.18.2 Solution
Use the station-to-station protocol for two-way authentication. A
simple modification provides one-way authentication. For example, the
server may not care to authenticate the client using public key
cryptography.
8.18.3 Discussion
|
Remember, authentication requires a trusted third party or a secure
channel for exchange of public DSA keys. If you'd
prefer a password-based protocol that can achieve all the same
properties you would get from Diffie-Hellman and DSA, see the
discussion of PAX in Recipe 8.15.
|
|
Given a client initiating a connection with a server, the
station-to-station protocol is as follows:
The client generates a random Diffie-Hellman secret
x and the corresponding public value A. The client sends A to the server. The server generates a random Diffie-Hellman secret
y and the corresponding public value B. The server computes the Diffie-Hellman shared secret. The server signs a string consisting of the public values A and B
with the server's private DSA key. The server sends B and the signature to the client. The client computes the shared secret. The client validates the signature, failing if it
isn't valid. The client signs A concatenated with B using its private DSA key, and
it encrypts the result using the shared secret (the secret can be
postprocessed first, as long as both sides do the same processing). The client sends the encrypted signature to the server. The server decrypts the signature and validates it.
The station-to-station protocol works only if your Diffie-Hellman
keys are always one-time values. If you need a protocol that
doesn't expose the private values of each party, use
Recipe 8.16. That basic protocol can be adapted from RSA to
Diffie-Hellman with DSA if you so desire.
Unless you allow for anonymous connection establishment, the client
needs to identify itself as part of this protocol. The client can
send its public key (or a digital certificate containing the public
key) at Step 2. The server should already have a record of the client
based on its public key, or else it should fail. Alternatively, you
can drop the client validation steps (9-11) and use a traditional
login mechanism after the encrypted link is established.
|
In many circumstances, the client
won't have the server's public key
in advance. In such a case, the server will often send a copy of its
public key (or a digital certificate containing the public key) at
Step 6. In this case, the client can't assume that
the public signing key is valid; there's nothing to
distinguish it from an attacker's public key!
Therefore, the key needs to be validated using a trusted third party
before the client trusts that the party on the other end is really
the intended server. (We discuss this problem in Recipe 7.1 and
Recipe 10.1.)
|
|
8.18.4 See Also
Recipe 7.1, Recipe 8.15, Recipe 8.16, Recipe 10.1
|