使用 Google Cloud Key Management Service 签署 JSON Web 令牌

2023-11-25

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

我正在开发 NodeJS 身份验证服务器,我想使用 google 签名来签署 JSON Web 令牌 (JWT)。

我正在使用 Google Cloud 密钥管理服务 (KMS),并创建了一个密钥环和一个非对称签名密钥。

这是我获取签名的代码:

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)

我正在使用的代码:

signing:

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 进行签名。

[代码添加到问题后编辑 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Google Cloud Key Management Service 签署 JSON Web 令牌 的相关文章

随机推荐

  • GNU 的 Java 编译器 (GCJ) 已经死了吗? [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 截至 2010 年 10 月 GNU 的 Java 编译器死的 是否有任何有效的替代方案 特别是将 Java 编译为本机代码 LLVM 解决方案将是首选 你可以使用IKVM and
  • WCF Duplex 是一个好的选择吗?

    在使用 WCF duplex 聊天服务 短信服务 开发迷你项目后 我得到了一个可能不正确的观点 我相信双工理论很好而且很有用 但是使用时有很多问题Wcf 复式 如可靠会话 超时例外 服务器端的客户端地址管理 客户端的代理管理 我想错了吗 我
  • 如何加速特征库矩阵乘积?

    我正在使用 Eigen 库研究两个大矩阵的简单乘法 对于相同大小的矩阵 这种乘法似乎明显慢于 Matlab 和 Python 有什么办法可以让 Eigen 运算更快吗 问题详情 X 随机 1000 x 50000 矩阵 Y 随机 50000
  • Studio BumbleBee 撰写预览的“渲染问题”

    我无法在 Studio 中预览任何内容 无法预览像Text 我收到 渲染错误 显示了该堆栈跟踪 java lang NoSuchMethodException com
  • 注入应用程序配置的最佳方式

    好吧 我正在尝试进入这个奇妙的网站 并提出一个有关将配置设置注入应用程序组件的正确方法的问题 所以 概述是 我有一个用 C Net 3 5 编写的应用程序 它由 3 个组件组成 核心 数据和服务 数据和服务程序集需要从 app config
  • UserControl 中不允许出现文字内容

    如何允许我的控件在其标签内包含文本
  • 打开一个大的 JSON 文件

    当我尝试使用以下命令打开时 我有一个 1 7 GB JSON 文件json load 然后它给出内存错误 如何在Python中读取JSON文件 我的 JSON 文件是一个包含特定键的对象的大数组 Edit 当然 如果 最外面的 数组中的每个
  • Bootstrap 4 卡组,其列数基于视口

    我正在尝试在 Bootstrap 4 中实现卡片组功能 以使所有卡片具有相同的高度 Bootstrap 提供的示例显示了 4 张漂亮的卡片 但无论视口如何 这都是 4 张卡片排成一行 查看代码here 这对我来说没有意义 因为我认为您希望卡
  • JFreeChart 的放大和缩小功能行为异常?

    我观察到 放大 和 缩小 的功能实现方式与预期完全不同 例如 当我执行一步 缩小 然后在退一步 缩放 后 再次执行 放大 和 缩小 功能 在 我再也看不到原始图表了 我没有看到 JFreechart 的 放大 和 缩小 功能同步 publi
  • SceneKit 水就像 Badger 示例中的那样

    有谁知道如何创建水材料 就像苹果公司的獾例子一样 scene scn 中有一个 geotherm 01 对象 该对象获得材质 1 terrasses orange water 和 1 terrasses eau 它用看起来逼真的慢速动画创建
  • 使用 Java 在 Google App Engine 中进行分页

    我需要创建简单的对象分页 但是当我阅读手册时 我发现 query setRange 5 10 即使只需要 5 个对象 也会获取 10 个对象 有没有办法获取刚需要的对象 编辑 我开始了赏金 所以你可以向我展示可以运行的简单 Java 示例代
  • 使用通用存储库和存储过程

    我正在开发一个首先使用通用 Repo 模式和 EF6 数据库的现有应用程序 我正在调用一个存储过程 它返回一个复杂类型 该类型不是我的实体模型中的现有实体 因此我不确定要给出什么类型 这就是从我的服务层调用我的 sp 的方式 unitOfW
  • 如何将自定义证书颁发机构(CA)添加到nodejs

    我正在使用 CLI 工具构建混合移动应用程序 该应用程序具有很酷的上传功能 因此我可以在设备上测试该应用程序 而无需通过应用程序商店 它是 ionic cli 然而 在我的公司中 像许多其他公司一样 TLS 请求是使用公司自己的自定义 CA
  • C++中如何访问类变量

    在c 中是否可以在不创建对象的情况下访问其他类中的类变量 我尝试使用静态 但另一个类无法识别我的变量 我有3节课 其中两个应该使用 sae 变量 在第三堂课中我正在改变价值观 如果您能提供帮助 我将不胜感激 也许你有一个例子 class M
  • 页面滚动后,jQuery 可拖动在错误的位置显示帮助程序

    我正在使用 jQuery可拖动的 and 可丢弃的对于我正在开发的工作计划系统 用户将作业拖到不同的日期或用户 然后使用 ajax 调用更新数据 一切工作正常 除了当我向下滚动主页时 工作出现在超出浏览器窗口底部的大型周计划表上 如果我尝试
  • 基于视图的 NSOutlineView 没有 NIB?

    NSOutlineView是一个子类NSTableView 而目前 NSTableView支持两种实现 基于细胞 基于视图 制作 OSX 10 8 Finder 风格的侧边栏 具有自动灰色图标样式 需要使用基于视图的表视图和源列表突出显示样
  • 如何从路径中提取每个文件夹名称?

    我的路径是 server folderName1 another name something another folder 如果我不知道路径中有多少个文件夹并且不知道文件夹名称 如何将每个文件夹名称提取到字符串中 非常感谢 string
  • 无法在 __init__.py django 1.9.4 中导入模型

    我的目录结构是 Mypack gt init py gt admin py gt apps py gt foo py gt models py 在 apps py 中 我有 AppConfig 我在 foo py 中有一些方法 它们使用从
  • EscapeUriString 和 EscapeDataString 有什么区别?

    如果只处理url编码 我应该使用转义Uri字符串 我对现有的答案不满意 所以我决定更深入地挖掘来解决这个问题 令人惊讶的是 答案非常简单 有 几乎 没有正当理由使用Uri EscapeUriString 如果您需要对字符串进行百分比编码 请
  • 使用 Google Cloud Key Management Service 签署 JSON Web 令牌

    编辑 我找到了答案 滚动到这个问题的底部 我正在开发 NodeJS 身份验证服务器 我想使用 google 签名来签署 JSON Web 令牌 JWT 我正在使用 Google Cloud 密钥管理服务 KMS 并创建了一个密钥环和一个非对