I'm using a technique borrowed out of a book by Bruce Schneier and Niels Ferguson called Practical Cryptography. Basically, it boils down to this:
Bob does this:
pubk_A = Alice's public key
entropy = bytes from PRNG
encrypted_entropy = RSA_Encryptpubk_A(entropy)
hashed_entropy = SHA2-512(entropy)
encrypt_keyBA = hashed_entropy[0:32]
encrypt_nonceBA = hashed_entropy[32:48]
hmac_keyBA = hashed_entropy[48:64]
Bob then sends encrypted_entropy to Alice.
Then Alice does this:
privk_A = Alice's private key
entropy = RSA_Decryptprivk_A(encrypted_entropy)
hashed_entropy = SHA2-512(entropy)
encrypt_keyBA = hashed_entropy[0:32]
encrypt_nonceBA = hashed_entropy[32:48]
hmac_keyBA = hashed_entropy[48:64]
This works great for generating keys that can be used to communicate from Bob to Alice. But I need keys I can use in both directions. I was thinking of modifying the algorithm in this way:
Bob does this with entropy:
pubk_B = Bob's public key
hashed_entropyBA = SHA2-512(SHA2-256(pubk_A) || entropy)
encrypt_keyBA = hashed_entropy[0:32]
encrypt_nonceBA = hashed_entropy[32:48]
hmac_keyBA = hashed_entropy[48:64]
hashed_entropyAB = SHA2-512(SHA2-256(pubk_B) || entropy)
encrypt_keyAB = hashed_entropy[0:32]
encrypt_nonceAB = hashed_entropy[32:48]
hmac_keyAB = hashed_entropy[48:64]
Alice can do the same thing on her side after she obtains entropy by decrypting encrypted_entropy.
As you can see, now there are two sets of keys, one used for communicating from Bob to Alice, and another for communicating from Alice to Bob.
Is there anything wrong with this? What security risks am I taking? Is the security of the system less or more than if I simply had one party tweak a bit in the nonce? Is there a better way to handle this problem without adding round-trips?
+
? Is it concatenation, addition modulo 2^512, bitwise xor, or something else? Also, is it reasonable to assume both endpoints know Bob's public key as well as Alice's public key? If you can clarify those points, I'll be glad to try to share some analysis of this. – D.W. Mar 29 '11 at 6:22+
as concatenation. It is reasonable to assume that both endpoints know both Alice's and Bob's public key. This is partly because Alice's name for Bob is SHA2-256(pubk_B), and Bob's name for Alice is SHA2-256(pubk_A). – Omnifarious Mar 29 '11 at 6:40