There was a brief discussion at OSW about signing vs encryption for JWT-based 
access tokens. I think it was Brian Campbell that pointed out that you often 
want authenticated encryption rather than signing, and I agree with this.

Currently JOSE only supports authenticated encryption for symmetric 
cryptography, which means that the AS and RS must agree a shared secret key 
beforehand. (Or else the RS uses the token introspection endpoint and doesn’t 
decrypt the token itself). Symmetric cryptography is less than ideal when the 
AS and RS are in separate trust boundaries (e.g., different companies).

There are actually ways to do *public key* authenticated encryption, but JOSE 
doesn’t support them yet. I wrote a 3-part blog series about this recently [1], 
but I’ll summarise the tl;dr version here. I think for JWT-based access tokens 
that contain identity assertions, this is probably what you want in most cases 
as it provides both confidentiality and authenticity without needing a bulky 
nested signed-then-encrypted JWT. Is this something people would be interested 
in, if I propose a draft?

Details:

The basic idea is to introduce one or more variants on ECDH-ES that provide 
sender authentication. The most straightforward is to use ECDH-SS — i.e., 
Diffie-Hellman between two static key pairs, one for the sender and one for the 
recipient, with no ephemeral keys. This provides authenticated encryption so 
long as the content encryption method is authenticated (which they all are in 
JOSE). But it has a number of security downsides, which I describe in more 
detail in the blog. (It might be useful in some IoT scenarios though).

The better variant is to instead do ECDH-ESSS. That is, we generate a random 
ephemeral key pair and do an agreement with the recipient’s static public key, 
just like in ECDH-ES, but then we do another key agreement between the sender’s 
static private key and the recipient’s static private key. We then concatenate 
the two shared secrets and feed them into ConcatKDF just like you would for 
ECDH-ES. This is what NIST SP.800-56A [2] calls the “one-pass unified model” 
(section 6.2.1.2). If you squint a bit then it is also very similar to the “K” 
one-way pattern in the Noise protocol framework [3].

To spell it out, the process for encrypting a JWE with this new scheme is as 
follows:

Sender has long-term “static” key pair: ssk,_spk (ssk = sender secret key, etc)
Recipient has long-term static key pair: rsk, rpk

1. Sender generates a random ephemeral key pair: esk, epk
2. Calculate Ze := ecdh(esk, rpk)  — just like in ECDH-ES
3. Calculate Zs := ecdh(ssk, rpk)
4. Let Z = Ze || Zs where || is concatenation
5. Run Z through ConcatKDF with PartyUInfo/PartyVInfo just as in ECDH-ES
6. Encrypt the message using the chosen “enc” encryption method using the key 
derived in step 5.

On its own ECDH-ESSS has some decent security properties (including 
authenticated encryption), but it is especially good when you want to exchange 
lots of messages with the recipient. If the recipient replies to your initial 
message using ECDH-ESSS but using the ephemeral public key you sent in the 
first message as if it was your static public key, then what you get is an 
interactive handshake very similar to the Noise KK pattern [4] (squinting quite 
hard at this point). Both parties can then use the derived key from step 5 of 
the second message as a shared session key and send “direct” encrypted JWEs to 
each other from that point on. This provides very strong security properties 
listed later in the Noise spec, including forward secrecy and both sender and 
recipient authentication with resistance to key compromise impersonation. So 
beyond its usefulness for Access Token JWTs, this scheme is a really versatile 
building block that you can use for lots of advanced use-cases (e.g., PoP 
schemes).

There are even nice formal models of the Noise handshake patterns in ProVerif 
[5], but I think they are only valid for the specific details of how Noise 
performs key derivation and transcript hashing so they wouldn’t directly apply 
to a JOSE version.

[1] 
https://neilmadden.blog/2018/11/14/public-key-authenticated-encryption-and-why-you-want-it-part-i/
 
<https://neilmadden.blog/2018/11/14/public-key-authenticated-encryption-and-why-you-want-it-part-i/>
[2] https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf 
<https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf>
[3] https://noiseprotocol.org/noise.html#one-way-handshake-patterns 
<https://noiseprotocol.org/noise.html#one-way-handshake-patterns> 
[4] 
https://noiseprotocol.org/noise.html#interactive-handshake-patterns-fundamental 
<https://noiseprotocol.org/noise.html#interactive-handshake-patterns-fundamental>
 
[5] https://noiseexplorer.com <https://noiseexplorer.com/>

Cheers,

Neil
_______________________________________________
OAuth mailing list
OAuth@ietf.org
https://www.ietf.org/mailman/listinfo/oauth

Reply via email to