Chapter 2 · Practice 4 of 4
Encrypt to a public key with HPKE or a sealed box, not raw RSA
Why it matters
When the sender should not hold a decryption key (a browser encrypting to your backend, one service sealing data for another), you need public-key encryption. OWASP's guidance:
- Use a maintained library implementing an established hybrid scheme such as HPKE (RFC 9180).
- X25519 is a key agreement primitive. On its own it does not encrypt data; it is one step inside a scheme like HPKE or libsodium's sealed boxes.
- HPKE's base mode does not authenticate the sender. If the recipient must know who sent it, use an authenticated mode or add a signature.
- If you must use RSA, keys are at least 2048 bits and encryption uses RSAES-OAEP. Never RSA without an encryption padding scheme.
Hybrid schemes encrypt the data with a fresh symmetric key and use the public key only to protect that key. That is also why OWASP notes that the post-quantum ML-KEM does not replace AES for encrypting stored data: it replaces the key establishment step.
libsodium's crypto_box_seal is a simple option for anonymous sealed messages: anyone with the public key can encrypt, only the private key holder can open.
Avoid
- RSA with PKCS#1 v1.5 or no padding for new encryption code
- Using X25519 output directly as an encryption key without a KDF
- Assuming HPKE base mode tells you who sent the message