gpt4 book ai didi

node.js - 使用 Google Cloud Key Management Service 签署 JSON Web Tokens

转载 作者:搜寻专家 更新时间:2023-10-31 23:50:14 24 4
gpt4 key购买 nike

编辑:我找到了答案。滚动到该问题的底部。

我正在使用 NodeJS 身份验证服务器,我想使用谷歌签名签署 JSON Web token (JWT)。

我使用的是 Google 云 key 管理服务 (KMS),我创建了一个 key 环和一个非对称签名 key 。

这是我获取签名的代码:

signatureObject = await client.asymmetricSign({ name, digest })

signature = signatureObject["0"].signature

我的 Google 签名对象如下所示:

enter image description here

我的问题:如何使用 Google 签名签署 JWT?

或者换句话说,我如何将 Google 签名连接到 JWT 的 (header.payload)?

JWT 应该看起来像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. (GoogleSignature)

我正在使用的代码:

签名:

async function sign(message, name) {
hashedMessage = crypto.createHash('sha256').update(message).digest('base64');
digest = { 'sha256': hashedMessage }

signatureObject = await client.asymmetricSign({ name, digest }).catch((err) => console.log(err))
signature = signatureObject["0"].signature
signJWT(signature)
}

创建 JWT:

function signJWT(signature) {
header = {
alg: "RS256",
typ: "JWT"
}

payload = {
sub: "1234567890",
name: "John Doe",
iat: 1516239022
}

JWT = base64url(JSON.stringify(header)) + "." +
base64url(JSON.stringify(payload)) + "." +
???signature??? ; // what goes here?
}

验证:

async function validateSignature(message, signature) {
// Get public key
publicKeyObject = await client.getPublicKey({ name }).catch((err) => console.log(err))
publicKey = publicKeyObject["0"].pem

//Verify signature
var verifier = crypto.createVerify('sha256');
verifier.update(message)
var ver = verifier.verify(publicKey, signature, 'base64')

// Returns either true for a valid signature, or false for not valid.
return ver
}

答案:

我可以像这样使用 toString() 方法:

signatureString = signature.toString('base64');

然后我可以使用

获取原始签名八位字节流
var buffer = Buffer.from(theString, 'base64');

最佳答案

您没有在您的问题中发布您的代码,所以我不知道您是如何构建用于签名的 JWT。

[在代码添加到问题后编辑 1/18/2019]

您的代码正在反向执行签名。您正在创建签名并尝试将其附加到 JWT Headers + Payload。您想要取而代之的是获取 JWT header + 有效负载并对数据进行签名,然后将签名附加到 JWT 以创建 Signed-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 之前,您可能必须先转换它。

[结束编辑]

示例数据:

JWT header :

{
alg: RS256
kid: 0123456789abcdef62afcbbf01234567890abcdef
typ: JWT
}

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": "someone@example.com.com",
"email_verified": "true",
"access_type": "offline"
}

算法:

SHA256withRSA

创建签名 JWT (JWS):

第 1 步:获取 JWT header 并转换为 Base-64。我们称其为 hdr_b64。

第 2 步:获取 JWT 负载并转换为 Base-64。我们称其为 payload_b64。

第 3 步:用点 . 连接编码的 header 和有效负载:hdr_b64 + '.' + payload_b64`。我们称它为 body_b64。

第 4 步:通常 JWS 使用私钥使用 SHA256withRSA 进行签名,通常称为“RS256”:

signature = sign(body_b64, RS256, private_key)

现在将签名转换为 Base-64。让我们称之为 signature_b64。

创建最终的 JWS:

jws = body_b64 + '.' + signature_b64。

建议:

您想使用 KMS 创建签名的 JWT 吗?我不会推荐这个。访问存储在 KMS 中的 key 是有成本的。 Signed-JWTs 使用私钥签名并使用公钥验证。你打算如何发布公钥?您在访问私钥和公钥时需要什么性能级别(您将多久进行一次签名和验证)?

当您在 Google Cloud Platform 中创建服务帐户时,系统会为您创建一个 key 对。此 key 对具有一个 ID,该 ID 带有 Internet 上可用的公钥,私钥存在于服务帐户 Json 凭据文件中。我会使用服务帐户来创建签名 JWT,而不是 KMS 中的 key 对。

用于创建和签名的 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

关于node.js - 使用 Google Cloud Key Management Service 签署 JSON Web Tokens,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54250511/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com