# Is this a good communication scheme?

I'm writing a wrapper for a chat program to allow for end-to-end encryption. I'm using Python and PyCrypto to accomplish this. I'd like to use a well known library to do this, but to my knowledge, none exist that do what I'm looking for.

Here's the design of the handshake protocol.

Alice and Bob have previously generated long-term RSA-2048 keys $A$ and $B$ for signing. Alice initiates an encrypted connection with Bob by creating a new session RSA-2048 key $S$. Alice signs $[S_{public}, \text{"Alice"}]$ with $A_{private}$ using PSS padding to get $Sig_A$.

$$[A_{public}, S_{public}, \text{"Alice"}, Sig_A]$$

Revision: Alice includes her identity in the signature.

Side note: The generation of a new RSA-2048 key is for forward security. I realize generating a new RSA-2048 key is inefficient, but I have no good way of using ECC or Diffie-Hellman.

Bob then verifies $Sig_A$, rejecting the connection if it fails. Bob then matches $A_{public}$ against a list of known trusted keys. Bob then generates a random 512-bit shared secret $Sec$ and encrypts it with $S_{public}$ using OAEP padding to get $EncSec$. Bob signs $[EncSec, A_{public}, S_{public}, \text{"Alice"}, \text{"Bob"}]$ with $B_{private}$ using PSS padding to get $Sig_B$, and then sends the following:

Revision: $A_{public}$, $S_{public}$, and both party's identities are included in SigB.

$$[B_{public}, EncSec, \text{"Bob"}, Sig_B]$$

Alice verifies $Sig_B$, rejecting the connection if it fails. Alice matches $B_{public}$ against her own list of trusted keys. Alice decrypts $EncSec$ with $S_{private}$ to get $Sec$.

Revision: Alice signs $[EncSec, B_{public}, \text{"Alice"}, \text{"Bob"}]$ as $Sig_C$ and sends this to Bob. Bob then verifies $Sig_C$ and rejects the connection if it fails.

At this point, the users would each get a notification showing the fingerprint of the person they are talking to, and whether or not they have been matched against a known list of trusted keys. Fingerprints are generated as $SHA256(RSAPublicKey)$ truncated to 16 hex characters, with a colon added every 4 characters. This fingerprint can be verified with some hard-to-spoof method, such as a phone call.

Alice and Bob have now verified each other's identities and shared a secret value. They both derive encryption and MAC keys like this.

$$EncKey = HMAC_{SHA256}("0", Sec)$$ $$MACKey = HMAC_{SHA256}("1", Sec)$$

Note that the "0" and "1" are strings of length 1 each, not the literal numeric values 0 and 1.

Encrypting and sending a message happens like this. (Assuming $M$ is the message, and $Rand(x)$ is a cryptographic random number generator that returns $x$ random bits)

$$IV = Rand(128)$$ $$C = AES_{CFB}(M, EncKey, IV)$$ $$MAC = HMAC_{SHA256}(IV || C, MACKey)$$

$IV || C || MAC$ is then transmitted. On the receiving end, $MAC$ is checked, and the message is rejected if it fails. Otherwise, the message is decrypted and displayed.

Are there any problems with this? (Other than the obvious "don't roll your own crypto", as I'm fairly backed into a corner here)

That doesn't hide Bob's identity from eavesdroppers.
(The OP mentioned in chat that the OP isn't trying to do that.)

I can no longer spot any other problems with the key exchange part.

The encryption/decryption of application level data is vulnerable to arbitrary replays
and reflection and dropping. ​ The public MAC input should indicate direction and
message_number and [number of messages received]. ​ There should be a separate way
for it to securely indicate those three things without sending any application-level message, and a way for it to close_notify with a secure indication of those three things.

• Would a challenge/response of $HMAC(Nonce, MACKey)$ from each party after the key exchange constitute explicit authentication? Also, since Alice sends her public key, the ephemeral RSA key, and a signature related to the two, doesn't that protect against some attacker intercepting and replacing Alice's key with theirs? They cannot produce a valid signature relating to Alice's key, and their own key will not match Bob's trusted list, and it will show another fingerprint to the user. Unless I'm not understanding the concept of identity misbinding. – Daffy Jan 28 '16 at 1:47
• As I edited into my answer, I'm not sure your scheme even implicitly authenticates Bob to Alice. ​ If it does, then "a challenge/response of HMAC(Nonce,MACKey) from each party after the key exchange" would constitute explicit authentication, but would require that (in addition to IND-CPA) AES$_{\text{CFB}}$ be secure against a very weak type of CCA1 attack with 2 chosen ciphertexts. ​ (It ought to be provable that AES being ​ ​ ​ (continued ...) ​ ​ ​ ​ ​ ​ ​ ​ – user991 Jan 28 '16 at 2:38
• (... continued) ​ ​ ​ a (strong) PRP implies such security for AES$_{\text{CFB}}$, but I've made no attempt at checking that.) ​ That doesn't "protect against some attacker intercepting and replacing Alice's key with theirs", although if "their own key will not match Bob's trusted list" then that would protect against such identity misbinding. ​ Will you also be assuming that the attacker's "own key will not match" Alice's trusted list? ​ ​ ​ ​ ​ ​ ​ ​ – user991 Jan 28 '16 at 2:39
• Wouldn't the authentication be fixed with a challenge and response system mixed into the handshake protocol? $AES_{CFB}$, under the ideal cipher model, should return random noise for any input (assuming IVs are not reused), since CFB mode essentially XORs the input with random data. By protection against an attacker replacing Alice's key, I meant that Bob could easily detect it and reject the connection, since the attacker's key would appear foreign, and the attacker cannot sign under Alice's key. – Daffy Jan 28 '16 at 3:59
• I'll get to the rest later, but regarding your last point: ​ ​ ​ That's the identity misbinding attack succeeding. ​ "the user will just be alerted that they are talking to someone new", even though the plaintexts are still coming from the same person and are not known to adversary. ​ ​ ​ ​ ​ ​ ​ ​ – user991 Jan 28 '16 at 4:18