Re: Problems with public key decryption with RSA
From: William Stacey [MVP] (staceywREMOVE_at_mvps.org)
Date: Wed, 2 Feb 2005 11:23:59 -0500
> My final solution is, for encrypting :-
> Encrypt the data symmetrically with random key
> Encrypt the key / IV with fixed (pre-loaded) key
> Package as byte array
> Digitally sign hash (with Private key) on package and send to receiver
The "pre-loaded" key should be the public key of the server in your signed
assembly and/or embedded in your code. Also above you would have an issue
with securing the "Private key" at the clients. So a better solution may
1) Generate random symmetric key and iv.
2) Encrypt key / IV with public RSA key of server.
3) Encrypt data with symmetric key.
4) Sign hash and sign data elements with HMAC-SHA1 using symmetric key.
Note we use the HMAC-SHA1 to sign as we don't have a RSA private key. We
could however create one dynamically for the session and encrypt our public
xml string in the request using RSA public key of server. However, as we
need the new RSA key only for signing the request, we can avoid that and
just use a keyed hash like HMAC-SHA1. You could also encrypt the resulting
signature using the server's public RSA key - but don't think that is
5) Server decrypts key / IV with it's private key.
6) Server verifies hash with HMAC-SHA1 using the key.
7) Server decrypts data with key / iv.
8) Server generates reply.
9) Server encrypts data with key / iv.
10) Server signs data elements with RSA private key.
11) Client verifies signature using RSA public key.
12) Client decrypts data and uses.
This does not require any prior stored private key on client's - only during
the session. This follows the SSL pattern where key exchange is done using
RSA pki first and after that symmetric encryption is used. You could also
modify to allow server to contribute to the entropy of the shared key, but
that would require a request/reply pair before you could use symmetric
encryption and I am not sure how much value that would as with above model
you still can get the shared key unless you brute force pki to discover it
using all combinations keys. For that reason, I would keep your shared key
as large as possible - say 64-100 bytes. Then both sides will use the sha1
hash of the 64 bytes or just the first 16-32 bytes for your AES crypto. You
may also want to include a Timestamp and/or msg ID on the requests to help
prevent reply attacks. Cheers!