您没有在问题中发布代码,所以我不知道您如何构建 JWT 进行签名。
[代码添加到问题后编辑 2019 年 1 月 18 日]
您的代码正在向后进行签名。您正在创建签名并尝试将其附加到 JWT 标头 + 有效负载。您希望采用 JWT 标头 + 有效负载并对该数据进行签名,然后将签名附加到 JWT 以创建签名 JWT。
使用您的源代码的伪代码:
body_b64 = base64url(JSON.stringify(header)) + "." + base64url(JSON.stringify(payload))
signature = sign(body_b64, name);
jwt = body_b64 + '.' + base64url(signature)
注意:我不确定签名返回的数据格式是什么signatureObject["0"].signature
。在转换为 Base64 之前,您可能必须先对其进行转换。
[编辑结束]
示例数据:
智威汤逊头部:
{
alg: RS256
kid: 0123456789abcdef62afcbbf01234567890abcdef
typ: JWT
}
智威汤逊有效负载:
{
"azp": "123456789012-gooddogsgotoheaven.apps.googleusercontent.com",
"aud": "123456789012-gooddogsgotoheaven.apps.googleusercontent.com",
"sub": "123456789012345678901",
"scope": "https://www.googleapis.com/auth/cloud-platform",
"exp": "1547806224",
"expires_in": "3596",
"email": "[email protected]",
"email_verified": "true",
"access_type": "offline"
}
算法:
SHA256withRSA
创建签名 JWT (JWS):
步骤1:
获取 JWT 标头并转换为 Base-64。我们称之为 hdr_b64。
第2步:
获取 JWT 有效负载并转换为 Base-64。我们称之为payload_b64。
步骤3:
用点连接编码的标头和有效负载.
之间:hdr_b64
+ '.' +有效负载_b64`。我们称之为 body_b64。
步骤4:
通常,JWS 使用私钥通过 SHA256withRSA(通常称为“RS256”)进行签名:
signature = sign(body_b64, RS256, private_key)
现在将签名转换为 Base-64。我们将此称为signature_b64。
创建最终的 JWS:
jws = body_b64 + '.' + 签名_b64。
建议:
您想使用 KMS 创建签名 JWT 吗?我不会推荐这个。访问 KMS 中存储的密钥需要付费。签名 JWT 使用私钥进行签名并使用公钥进行验证。您将如何发布公钥?您在访问私钥和公钥时需要什么性能级别(您签名和验证的频率)?
当您在 Google Cloud Platform 中创建服务帐户时,系统会为您创建一个密钥对。该密钥对有一个 ID,其中包含 Internet 上可用的公钥,而私钥则存在于服务帐户 Json 凭证文件中。我将使用服务帐户来创建签名 JWT,而不是 KMS 中的密钥对。
用于创建和签名的 Python 示例代码:
def create_signed_jwt(pkey, pkey_id, email, scope):
'''
Create a Signed JWT from a service account Json credentials file
This Signed JWT will later be exchanged for an Access Token
'''
import jwt
# Google Endpoint for creating OAuth 2.0 Access Tokens from Signed-JWT
auth_url = "https://www.googleapis.com/oauth2/v4/token"
issued = int(time.time())
expires = issued + expires_in # expires_in is in seconds
# Note: this token expires and cannot be refreshed. The token must be recreated
# JWT Headers
headers = {
"kid": pkey_id, # This is the service account private key ID
"alg": "RS256",
"typ": "JWT" # Google uses SHA256withRSA
}
# JWT Payload
payload = {
"iss": email, # Issuer claim
"sub": email, # Issuer claim
"aud": auth_url, # Audience claim
"iat": issued, # Issued At claim
"exp": expires, # Expire time
"scope": scope # Permissions
}
# Encode the headers and payload and sign creating a Signed JWT (JWS)
sig = jwt.encode(payload, pkey, algorithm="RS256", headers=headers)
return sig