嵌套 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】:说明
每个内容加密算法(AxxxGCM
和 AxxxCBC_HSxxx
)都使用对称密钥(CEK
)。此密钥由密钥加密算法及其密钥管理模式(随机 CEK、密钥协商、直接密钥...)确定。
您是对的,与AxxxGCM
算法相反,AxxxCBC
算法不是经过身份验证的加密算法。
但是,RFC7516 section 5.1 item 15.(JWE 规范)引入了一个标签,允许验证密文并保护受保护标头的完整性(这就是 AxxxCBC
算法与 HSxxx
一起使用的原因)。
RFC7518 section 5.1 中的表格证实了这一点。详细信息在下一节中给出。
在任何情况下,您都需要 2 种算法来进行 JWE 计算:
密钥加密算法:您提到您有一个非对称密钥,所以我猜您会根据您的密钥类型选择RSA
或ECDH-ES
算法。
内容加密密钥:AxxxGCM
或AxxxCBC_HSxxx
算法。使用 JWE 规范,两者都提供经过身份验证的加密。我个人更喜欢 AxxxGCM
算法,因为它们在我的环境中更快。
回答
您表示要签名和加密,但您不能在客户端隐藏密钥,因此无法保证签名。
如果您只加密(仅限 JWE),您的服务器将无法验证令牌的颁发者。
【讨论】:
感谢您的详细回答。澄清一下:我需要在服务器上签名并在客户端上验证(真实性/发行人)。我不需要在服务器上验证。服务端会有私钥,客户端可以相对安全地拥有公钥。 好的,如果您的服务器与您的客户端共享公钥,那没有问题以上是关于嵌套 JWS + JWE 与具有身份验证加密的 JWE的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Boot 中使用 Keycloak 实现 JWT、JWE 和 JWS(签名 JWT)