Disclaimer: This is a learning-oriented question. I'm not trying to design a new protocol or roll my own crypto.
Suppose Alice has an RSA keypair. Alice shares the public key only with Bob. Bob wants to send Alice an encrypted message, and starts out with the following:
- $msg :=$ Plaintext message.
- $pubkey :=$ Alice's RSA public key.
Bob generates the following additional parameters:
- $symkey :=$ Randomly-generated symmetric encryption key (e.g., AES).
- $iv :=$ Randomly-generated initialization vector for symmetric encryption.
- $encmsg :=$ Result of symmetrically encrypting $msg$ using $symkey$ and $iv$.
- $sig :=$ HMAC signature of $encmsg$ using $symkey$ as the HMAC secret.
- $enckey :=$ Result of RSA-encrypting (OAEP) $symkey$ using public key $pubkey$.
Bob sends Alice $(enckey,\ sig,\ encmsg,\ iv)$. Alice reverses the steps Bob took in order to derive and verify the message:
- $symkey :=$ Result of RSA-decrypting (OAEP) $enckey$ using Alice's private RSA key.
- $sig2 :=$ HMAC signature of $encmsg$ using $symkey$ as the HMAC secret.
- Ensure $sig = sig2$.
- $msg :=$ Result of symmetrically decrypting $encmsg$ using $symkey$ and $iv$.
Assuming that Alice can successfully verify Bob's HMAC signature, and because Alice's public key was only shared with Bob, can Alice trust that Bob must have been the sender?
The inspiration for this question comes from how Microsoft Graph encrypts resource data in change notifications. "Alice" is the application. "Bob" is Microsoft. The application subscribes to change notifications with Microsoft and provides a public key (via encryptionCertificate). Microsoft uses the public key to encrypt resource data in payloads.
Granted, Microsoft also includes validationTokens in such notification payloads, which is intended for verification of authenticity. For this question, I'm wondering what level of authenticity can be obtained by successful decryption alone, without considering validationTokens. (Again, for the purposes of learning, not to actually skip this step in practice.)
On a somewhat separate note, I noticed that the JWTs in validationTokens are only bound with the notification payload by the tid JWT claim matching the tenantId of the payload, which seems like a very weak binding: Suppose an attacker intercepts one of the notification payloads. The attacker can modify the notification payload (while preserving the tenantId), and submit the payload with the same validationTokens. I believe this tampering would not be detectable via the JWT validation recommended by Microsoft. Does this concern seem valid?