[Botan-devel] bi-directional communication using single private/passphrase - public key setup

Jack Lloyd lloyd at randombit.net
Thu Jan 28 09:50:31 EST 2010

On Thu, Jan 28, 2010 at 10:08:27AM +0000, Paul Clark wrote:

> Could they not use sign() at the server and verify() at the client for 
> the server-to-client direction, and normal encrypt() at the client and 
> decrypt() at the server for the other way?

In terms of botan's interface, no, because all that verify() returns
is a single bit saying if the signature is valid or not. That is
because the library supports signature schemes with recovery (RSA, NR,
Rabin-Williams) and without recovery (DSA, ECDSA). [And using RSA or
RW with certain padding schemes, such as PSS, turn RSA/RW into a
signature scheme without recovery].

In the case of bare RSA you could indeed encrypt with the private
exponent ('sign') in mathematical terms, however doing so is not a
good idea. If you use a normal small exponent (17, 65537), then
obviously anyone can decrypt it simply by guessing your exponent. If
you chose a large public exponent, then both sides will not only be
quite slow but I'm fairly sure there are various possible attacks (a
quick google didn't pull up the relavant papers and I need to get to
work so consider it an excercise for the reader).

And, finally and (IMO) fatally, doing this completely screws you on
key management. It fixes your entire system with a single key. If a
client is ever reverse engineered [*], then the public key is
known. That doesn't get you back the server's private key, but with
just the 'public' key you can read anything the server sends to ANY
CLIENT. And if the servers key is ever compromised, you are similiarly
done for.

Doing key management is hard, but doing better than this is really
easy. Create a CA certificate. Embed the CA cert in every client. Sign
the server certificate with the CA private key, keeping the CA key in
secure offline storage the rest of the time. On first startup, clients
automatically create a self-signed cert. Server sends out their cert.
Client verifies and sends theirs. Key exchange commences. When the
servers key becomes compromised, issue a new cert. It's no SSL (and
that people keep wanting to do things like this is one reason I'm
going to be working on including SSL in 1.10 so it can be over and
done with), but it's certainly a huge improvement over hardcoding a
key everywhere.


[*]: And if the objection is 'nobody will ever bother reverse
engineering the client to break the security, it's not worth the
bother', then clearly whatever you are doing doesn't need to be done
at all.

More information about the botan-devel mailing list