美文网首页
【译】如何为应用程序选择 JOSE / JWT 加密算法

【译】如何为应用程序选择 JOSE / JWT 加密算法

作者: 舌尖上的大胖 | 来源:发表于2019-10-22 14:46 被阅读0次

    本文翻译自 How to select a JOSE / JWT cryptographic algorithm for your application

    JOSE 即 JavaScript Object Signing and Encryption,已采用了一系列标准加密算法,包括新的 Edwards 曲线算法(2017年新增)。那么应该使用哪种算法来保护 JWT 或应用程序中的其他对象呢?本指南将提供一些基本准则,以便做出明智的选择。 但是,也请咨询该领域的文章,文献和专家,以仔细检查您的假设,并确保没有遗漏任何重要问题。

    一、常见的数据安全关注点

    我们保护数据(例如令牌)的需求通常来自一个或多个关注的问题:

    • 完整性
      关注数据未被篡改
    • 真实性
      关注可以验证数据的来源
    • 不可抵赖
      数据的来源必须可由其他人验证
    • 保密
      对未经授权的各方和操作保密

    选择合适的 JOSE 算法的第一步,是了解我们所关注的安全因素。

    二、可用的 JOSE 算法类

    JOSE 提供了三种截然不同的加密算法类,以解决四个安全问题,它们具有部分重叠的属性:

    算法 完整性 真实性 不可抵赖性 保密性
    HMAC
    数字签名
    认证加密

    HMAC 算法:一种特殊的超高效哈希(HMAC),用于确保数据的完整性和真实性。 为了计算 HMAC,您需要一个密钥

    数字签名:提供 HMAC 的特性,以及加密的不可否认性(使签名者以外的其他人可以检查签名的有效性)。 数字签名基于公钥/私钥密码术。 需要一对公钥/私钥(类型为 RSA,椭圆曲线(EC)或爱德华兹曲线八位密钥对(OKP))。

    认证加密:在加密数据的同时,还确保其完整性和真实性(例如 HMAC)。 JOSE 通过公钥/私钥,秘密(共享)密钥和密码来提供加密。

    1、基于哈希的消息认证码(HMAC)

    • 功能:完整性、认证
    • JOSE 格式:JSON Web Signature(JWS)
    • 秘钥类型:密码
    • 算法:HMAC with SHA-2
      • HS256
      • HS384
      • HS512
    • 用例:
      • 存储在浏览器 Cookie 中的无状态会话
      • 电子邮件验证码
      • 会话 ID 能够区分过期 ID 和无效 ID
      • Token 的颁发者最终用户是==同一角色==
    • 备注
      • HMAC 不是数字签名!
      • 使用更长的密钥/哈希(例如 HS512 )以提高安全性
      • 长于哈希大小的密钥不能提供额外的安全性

    对于令牌和其他需要向外发送或存储的信息,如果最终由颁发它的应用程序使用,那么 HMAC 算法(带有 JOSE alg 标识符 HS256,HS384 和 HS512)是理想的选择。

    这里的主要关注点是确保:
    1)当我们取回数据时数据的完整性,以及
    2)数据实际上是由我们产生的。

    示例 JWT 声明了无状态会话 Cookie:

    {
      "sub"      : "user-12345",
      "email"    : "alice@wonderland.net",
      "login_ip" : "172.16.254.1", 
      "exp"      : 1471102267
    }
    

    一个常见的误解,是消息身份验证代码可以视为数字签名。 其实并不是! 这是因为验证的过程需要用到计算 HMAC 时使用的原始密钥,并且从本质上讲,该密钥不能与他人分享,因为不能让他人具备生成自己的 HMAC 的能力。 如果想要不可否认性,请使用 RSA,EC 或 EdDSA 签名

    2、数字签名

    数字签名适用于发行令牌、声明、断言和文档,且这些文档的完整性和真实性必须由其他各方进行验证的场景。

    使用示例:
    • 由 OpenID 提供者发行的身份令牌,依赖方需要对其进行验证才能登录用户。
    • 由 OAuth 2.0 服务器发出的访问令牌,资源服务器 / Web API 必须在提供请求之前对其进行验证。
    数字签名仅适用于公用/专用密钥:
    • 颁发者需要先生成 公钥/私钥对,然后才能对 JWT 或其他对象进行签名。
    • 签名是用私钥计算的,私钥必须始终保持安全,否则会有冒充的风险。
    • JWT 或 JWS 对象的签名需要使用公钥验证。接收者发现和下载公钥的方法是特定于应用程序的。 例如,OpenID Connect 服务器JWK 格式的 URL 上发布其公钥。
    选择哪种数字签名算法?
    • 如果您需要广泛的支持,请选择 RS256。 该算法基于 RSA PKCS#1,它仍然是公钥/私钥密码术使用最广泛的标准。 任何足够好的 JWT 库都应支持它。 RSxxx 签名也花费很少的 CPU 时间进行验证(有助于确保在资源服务器上快速处理访问令牌)。 推荐的 RSA 密钥长度为 2048 位。

    • ESxxx 签名算法使用椭圆曲线(EC)加密。 它们需要较短的密钥,并且产生较小的签名(相当于 RSA 强度)。 但是,EC 签名有一个缺点:它们的验证速度很慢

    • 新的 Edxxx 算法提供了最佳的签名/验证性能组合。 特别是通过 P-265 曲线签名,比2048 位 RSA 高 62 倍,比 EC DSA 高 14 倍。

    我们有 RSAECEdDSA 签名的 JWT 的示例。

    3、认证加密

    • 功能:机密性、完整性、认证

    • JOSE 格式:JSON Web Encryption(JWE)

    • 秘钥类型:

      • Public / private key pair:
        • RSA
        • EC
        • OKP
      • Secret (shared) key
      • Password
    • 算法

    • 用例

      • 签名和加密的ID令牌(OpenID Connect)
      • 签名并加密的自包含访问令牌(OAuth 2.0)
      • 加密的文档和数据,具有完整性和真实性检查
    • 备注

      • 保持私钥和私钥的安全!
      • 推荐的 RSA 密钥大小为 2048 位

    JOSE 通过以下方式提供加密:

    • 如果您想自己加密数据,请使用密钥。 如果秘密密钥是与其他方共享的(通过某种带外方式),则他们也可以使用它来加密数据/解密密文。 请查看上表,了解可用的密钥加密算法。

    • 收件人提供的公共密钥(RSA,EC 或 OKP)。 例如,OpenID Connect 提供程序以可发现的 URL 以 JWK 格式发布其公共密钥。 接收者然后可以使用其匹配的私钥解密 JWT / JOSE 对象。 在不可能或不可行带外通信的情况下,公钥/私钥密码术是理想的选择。

    • 如果您想使用可以记住的短语加密数据,则为密码。

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

    JWE 加密是一个“两步”过程:

    1、数据或内容始终使用 AES 密钥(称为内容加密密钥或 CEK)进行加密,并且每个 JWT / JWE 对象都使用不同的 CEK。 Nimbus 库将自动为您生成此 AES 密钥,并且其长度将取决于 enc(加密方法)标头参数(例如,"enc": "A128GCM" 将导致生成 128 位 AES 密钥)。 除了可以选择三种 AES 密钥长度(128、198 和 256)之外,JOSE 还支持两种内容加密模式:AxxxCBC-HSxxx 和 AxxxGCM。 通常,更广泛地支持 AxxxCBC-HSxxx 模式。

    2、第二步是使用输入密钥(即您提供的秘密密钥,公共密钥或密码)对生成的 AES CEK 进行加密(也称为包装)。 这由 alg JWE 标头参数指定。 如果要跳过第二步,直接提供 AES CEK,请选择直接加密并指定 "alg": "dir" JWE 标头参数。

    示例 JWE 标头,其中的内容在 GCM 模式下使用 128 位 AES 加密,而 AES CEK 本身使用公共 RSA 密钥加密(使用 RSA OAEP 加密):

    {
      "alg" : "RSA-OAEP",
      "enc" : "A128GCM"
    }
    

    您可以查看使用 RSA 公钥加密 JWT 的示例

    三、嵌套签名和加密

    可以对签名的 JWT / JWS 对象进行附加加密,从而为数据提供完整性,真实性,不可否认性和机密性。

    这是通过简单的嵌套实现的(请参见示例):

    1、JWT 用专用的 RSA,EC 或 OKP 密钥签名。
    2、然后,签名的 JWT 成为 JWE 对象的有效负载(纯文本),该JWE对象使用接收者的公钥(RSA,EC,OKP)或已在两方之间共享的秘密密钥进行加密。

    处理嵌套的 JWT 向后工作:

    1、使用适当的密钥(RSA,EC 或 OKP 的私钥或已建立的私钥)解密 JWE 对象。
    2、然后将提取的有效负载(纯文本)解析为签名的 JWT,并使用发行者的公钥(RSA,EC 或 OKP)进行验证。

    Nimbus JOSE + JWT 库提供了用于处理嵌套 JWT 的完整框架。

    四、OpenID Connect 中的算法选择

    通过以下规则,您可以了解在给定客户端注册后哪些 ID 令牌算法可行:
    1、具有 client_secret 的客户端可以接收由 HMAC(其中 client_secret 充当 HMAC 秘密密钥)或签名(RSA,EC 或 EdDSA)保护的 ID 令牌。 为了验证 RSA,EC 或 EdDSA 签名的 ID 令牌,客户端仅需要(从其 JWK 设置 URL 中)检索 OpenID 提供程序的匹配公钥。

    2、带有 client_secret 的客户端也可以接收加密的 ID 令牌,其中 client_secret 用于从中导出秘密 AES 密钥。

    3、如果使用 HMAC,则要求的 client_secrets 必须足够长以适合所需的密钥长度。 例如,一个 256 位 client_secret 允许 HMAC 与 HS256 一起使用。

    4、为了使客户端能够接收 RSAECDH 加密的 ID 令牌,它必须具备使用 OpenID 提供方注册的 RSA,EC 或 OKP 公钥。

    5、OpenID Connect 还允许没有 client_secret 的客户端。 此类客户端需要向 OpenID 提供程序注册的 RSA,EC 或 OKP 公钥,并使用该密钥在令牌端点进行身份验证(通过 JWT)。 如上所述,可以将 ID 令牌加密为该公共密钥。

    五、参考资料

    (完)

    相关文章

      网友评论

          本文标题:【译】如何为应用程序选择 JOSE / JWT 加密算法

          本文链接:https://www.haomeiwen.com/subject/tguqvctx.html