跳转到主要内容
Chinese, Simplified

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

常见的数据安全问题


我们保护数据(如令牌)的需求通常源于一个或多个问题:

完整

关注:该数据未被篡改

真实性

关注:可以验证数据的来源

 

不可否认

关注:数据的来源必须由其他人验证

 

 

保密

关注:该数据对未经授权的各方和流程保密

 

了解我们所追求的安全方面是选择合适的JOSE算法的第一步。

可用的JOSE算法类


JOSE提供三种不同类型的加密算法,以满足四个安全问题,具有部分重叠的属性:

  Integrity Authentication Non-repudiation Confidentiality
HMAC
 
   
Digital signatures  
Authenticated encryption  
  • HMAC算法:一种特殊的超高效散列(HMAC),用于确保数据的完整性和真实性。 为了计算HMAC,您需要一个密钥。
  • 数字签名:提供HMAC的属性,以及加密的不可否认性(允许除签名者之外的其他人检查签名的有效性)。 数字签名基于公钥/私钥加密。 需要公钥/私钥对(RSA类型,椭圆曲线(EC)或Edwards曲线八位字节密钥对(OKP))。
  • 经过身份验证的加密:加密数据,同时确保其完整性和真实性(如HMAC)。 JOSE使用公钥/私钥,秘密(共享)密钥和密码提供加密。

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

Provide Integrity, Authentication
JOSE format JSON Web Signature (JWS)
Key type Secret key
Algorithms HMAC with SHA-2:
  • HS256
  • HS384
  • HS512
Use cases
  • Stateless sessions stored in browser cookies
  • Email verification codes
  • Session IDs with the ability to differentiate between expired and invalid IDs
  • Tokens where issuer and ultimate consumer is the same party
Notes
  • The HMAC is not a digital signature!
  • Use longer keys / hashes (e.g. HS512) for increased security
  • Keys longer than the hash size don't provide additional security

HMAC算法(具有JOSE alg标识符HS256,HS384和HS512)是保护令牌和其他需要发送或存储在外部的信息的理想选择,以便最终由发布应用程序使用。这里的关键问题是确保1)数据恢复时的完整性,2)数据实际上是由我们生成的。

一个很好的例子是使用HMAC安全的JWT来生成无状态会话cookie。 JWT可以包括有关登录用户的ID和其他信息。当Web应用程序收到cookie时,重新计算HMAC并与JWT进行比较。如果两个HMAC不匹配,我们可以假设cookie已被篡改,或者不是我们的。

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

{
  “sub”:“user-12345”,
  “email”:“alice@wonderland.net”,
  “login_ip”:“172.16.254.1”,
  “exp”:1471102267
}
一种常见的误解是消息认证码符合数字签名的要求。他们没有!这是因为验证需要访问用于计算HMAC的原始密钥,并且就其性质而言,您无法与其他人共享该密钥,也无法让他们生成自己的HMAC。如果您想要不可否认性,请使用RSA,EC或EdDSA签名。

2.数字签名

Provide Integrity, Authentication, Non-repudiation
JOSE format JSON Web Signature (JWS)
Key type Public / private key pair:
  • RSA
  • EC
  • OKP
Algorithms RSA signature with PKCS #1 and SHA-2:
  • RS256
  • RS384
  • RS512
RSA PSS signature with SHA-2:
  • PS256
  • PS384
  • PS512
EC DSA signature with SHA-2:
  • ES256
  • ES384
  • ES512
Edwards-curve DSA signature with SHA-2:
  • Ed25519
  • Ed448
Use cases
  • ID tokens (OpenID Connect)
  • Self-contained access tokens (OAuth 2.0)
  • Passing security assertions and tokens between domains
  • Data which integrity and authenticity must be verifiable by others
Notes
  • Keep your private keys secret!
  • The recommended RSA key size is 2048 bits
  • EdDSA signatures offer the best performance

数字签名适用于发布令牌,声明,断言和文档,其完整性和真实性必须由其他方验证。

示例用途:

  • 由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算法提供了最佳的符号/验证性能组合。特别是签名在2048位RSA上提升62倍,在EC DSA上用P-265曲线提升14倍。

我们有RSA,EC和EdDSA签署的JWT的示例。

3.认证加密

Provide Confidentiality, Integrity, Authentication
JOSE format JSON Web Encryption (JWE)
Key type
  • Public / private key pair:
    • RSA
    • EC
    • OKP
  • Secret (shared) key
  • Password
Algorithms Public / private key encryption: Secret (shared) key encryption: Password based encryption:
  • PBES2:
    • PBES2-HS256+A128KW
    • PBES2-HS384+A192KW
    • PBES2-HS512+A256KW
Use cases
  • Signed and encrypted ID tokens (OpenID Connect)
  • Signed and encrypted self-contained access tokens (OAuth 2.0)
  • Encrypted documents and data, with integrity and authenticity check
Notes
  • Keep your private and secret keys secure!
  • The recommended RSA key size is 2048 bits

JOSE提供以下加密:

  • 一个密钥( secret key)。如果你想为自己加密数据。 如果密钥与其他方共享(by some out-of-band mean),它们也可以用它加密数据/解密密文。 请查看上表,了解可用的密钥加密算法。
  • 收件人提供的公钥(RSA,EC或OKP)。例如,OpenID Connect提供程序以可发现的URL以JWK格式发布其公钥。然后,收件人可以使用其匹配的私钥解密JWT / JOSE对象。公共/私有密钥加密是在无法或不可行地传送带外密钥的情况下的理想选择(Public / private key cryptography is ideal in situations where communicating a secret key out-of-band is not possible or feasible)。
  • 如果要使用您能记住的某些短语加密数据,请使用密码。

JOSE中的加密始终是经过身份验证的,这意味着密文的完整性可以防止被篡改。因此,经过身份验证的加密使得在JSON Web加密(JWE)冗余中嵌套HMAC JWT;仅使用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对象的有效载荷(明文),该对象用接收者的公钥(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令牌,客户端只需要检索OpenID提供程序的匹配公钥(来自其JWK集URL)。
  2. 具有client_secret的客户端也可以接收加密的ID令牌,其中client_secret用于从中获取秘密的AES密钥。
  3. 如果使用HMAC,则发布的client_secrets必须足够长以适合所需的密钥长度。例如,256位client_secret允许HMAC与HS256。
  4. 为了使客户端能够接收RSA或ECDH加密的ID令牌,它必须具有向OpenID提供者注册的公共RSA,EC或OKP密钥。
  5. OpenID Connect还允许没有client_secret的客户端。此类客户端需要向OpenID提供程序注册公共RSA,EC或OKP密钥,并使用该密钥在令牌端点进行身份验证(通过JWT)。如上所述,ID令牌可以被加密到该公钥。

原文:https://connect2id.com/products/nimbus-jose-jwt/algorithm-selection-guide

本文:http://pub.intelligentx.net/node/465

讨论:请加入知识星球或者小红圈【首席架构师圈】

Article
知识星球
 
微信公众号
 
视频号