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 cryptographic quality 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?