嵌套 JWS + JWE 与具有身份验证加密的 JWE

Posted

技术标签:

【中文标题】嵌套 JWS + JWE 与具有身份验证加密的 JWE【英文标题】:Nested JWS + JWE vs JWE with Authenticated Encryption 【发布时间】:2018-04-08 01:41:22 【问题描述】:

问题

我想在我的服务器(受信任的环境)上签名和加密(有效地,混淆)一些信息(“令牌”),并将密文发送到客户端机器(不太受信任的环境)以由我的阅读和验证客户端软件。这种类型的环境允许我在服务器上拥有一个用于非对称签名的私钥,但我不能在客户端“隐藏”一个用于对称签名的密钥。

替代品

我选择使用 JWT 作为标准,使用 Nimbus JOSE+JWT library 作为签名和加密的实现。 Nimbus 库提供了两个用于签名 + 加密的选项:将 JWS 嵌套到 JWE 中或将 JWE 与经过身份验证的加密算法(A128CBC_HS256、A192CBC_HS384 或 A256CBC_HS512)一起使用。 Algorithm Selection Guide for Nimbus 状态:

JOSE 中的加密始终经过身份验证,这意味着密文的完整性受到保护,不会被篡改。因此,经过身份验证的加密使得将 HMAC JWT 嵌套在 JSON Web 加密 (JWE) 中是多余的;仅使用 JWE 加密。

但是,AxxxCBC_HSxxx 加密方法仅使用对称密钥。此外,用 RSA JWE 算法替换直接 JWE 算法应该没有帮助,因为滥用者可以自己生成 CEK(由加密密钥和 HMAC 密钥组成)并使用公钥对其进行加密。

问题

尽管引用了嵌套 JWT 的冗余,但我得出结论,就我而言,JWE+JWS 嵌套是唯一可行的方法。我说的对吗?

【问题讨论】:

【参考方案1】:

说明

每个内容加密算法(AxxxGCMAxxxCBC_HSxxx)都使用对称密钥(CEK)。此密钥由密钥加密算法及其密钥管理模式(随机 CEK、密钥协商、直接密钥...)确定。

您是对的,与AxxxGCM 算法相反,AxxxCBC 算法不是经过身份验证的加密算法。 但是,RFC7516 section 5.1 item 15.(JWE 规范)引入了一个标签,允许验证密文并保护受保护标头的完整性(这就是 AxxxCBC 算法与 HSxxx 一起使用的原因)。

RFC7518 section 5.1 中的表格证实了这一点。详细信息在下一节中给出。

在任何情况下,您都需要 2 种算法来进行 JWE 计算:

密钥加密算法:您提到您有一个非对称密钥,所以我猜您会根据您的密钥类型选择RSAECDH-ES 算法。 内容加密密钥:AxxxGCMAxxxCBC_HSxxx 算法。使用 JWE 规范,两者都提供经过身份验证的加密。我个人更喜欢 AxxxGCM 算法,因为它们在我的环境中更快。

回答

您表示要签名和加密,但您不能在客户端隐藏密钥,因此无法保证签名。

如果您只加密(仅限 JWE),您的服务器将无法验证令牌的颁发者。

【讨论】:

感谢您的详细回答。澄清一下:我需要在服务器上签名并在客户端上验证(真实性/发行人)。我不需要在服务器上验证。服务端会有私钥,客户端可以相对安全地拥有公钥。 好的,如果您的服务器与您的客户端共享公钥,那没有问题

以上是关于嵌套 JWS + JWE 与具有身份验证加密的 JWE的主要内容,如果未能解决你的问题,请参考以下文章

结合 JWE 和 JWS

在 Spring Boot 中使用 Keycloak 实现 JWT、JWE 和 JWS(签名 JWT)

浅谈jwt

验证使用 JSON Web 加密 (JWE) 加密的安全令牌的颁发者?

JWT在python中加密有效载荷? (JWE)

一篇文章带你分清楚JWT,JWS与JWE