【问题标题】:Verifying JWT tokens generated with PHP in Node在 Node 中验证使用 PHP 生成的 JWT 令牌
【发布时间】:2022-01-04 19:06:04
【问题描述】:

我正致力于在使用 Webpack5 的客户端 Web 应用程序中实现 JWT 验证。当在运行 PHP 的后端创建用户时,我会创建一个公钥和私钥对,以便像这样在 JWT 中使用并存储它们:

$keyPair = sodium_crypto_sign_keypair();
$privateKey = base64_encode(sodium_crypto_sign_secretkey($keyPair));
$publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair));

然后使用firebase/php-jwt 创建这样的请求:

$jwt = JWT::encode($payload, $privateKey, 'EdDSA');

但是,使用jose 尝试验证 JWT 时出现以下错误:

import * as jose from 'jose';
const { payload, protectedHeader } = await jose.jwtVerify(response.token, window.atob(response.key));
console.log(payload);
console.log(protectedHeader);

TypeError: Key must be of type CryptoKey.

我不明白它如何想要密钥,因为 publicKey 的 base64 字符串和 base64 表示在节点中遇到了相同的 TypeError。我在这里做错了什么?

【问题讨论】:

  • 应该是keyLike
  • @LawrenceCherone 是的,当谷歌搜索出现的错误时。我阅读了文档页面,但显然我并不完全了解如何将 publicKey 转换为可接受的格式。
  • 这个问题的标题和标签是 Node.js,而实际上使用的运行时只是浏览器中的 javascript。

标签: php node.js jwt jose


【解决方案1】:

WebCryptography API 不支持 Edwards-Curve 数字签名算法(JOSE 中的 EdDSA),因此您不会成功使用任何使用本机浏览器加密的库。很遗憾。

有一个提议将 Ed25519、Ed448、X25519 和 X448 添加到 WebCrypto 中,但在采用和实施之前需要一段时间。发生这种情况时,jose 将支持此操作。话虽如此,您需要传递一个 CryptoKey。这可以通过 crypto.subtle.importKey 直接导入,也可以通过jose 的导入密钥函数导入。 SubtleCrypto 支持原始公钥导入,jose 仅在其包装器中支持 PEM 密钥导入。

浏览器算法支持矩阵见Browser Support,算法密钥要求见Algorithm Key Requirements ,如何获得正确的密钥表示形式见Type alias: KeyLike

至于其他(现已删除)的建议,他们没有考虑到您使用的算法,建议使用 Uint8Array 代替 CryptoKey 是错误的,Uint8Array 使用是对称算法专有的。同样,使用转译的jsonwebtoken 仅对于基于 HMAC 的算法是远程可靠的。

jose 仅使用运行时的本机加密层,这是您在一致性和安全实施方面的最佳选择,但在运行跨运行时时,您需要考虑平台上支持的算法的交集。

我不明白它是如何想要密钥的,因为 publicKey 的 base64 字符串和 base64 表示在节点中都遇到了相同的 TypeError

它应该是 KeyLike(接口)——在 Node 中它是 KeyObject(参见加密文档),在类似 Web 的环境中它是 CryptoKey(参见 WebCryptoAPI)。

【讨论】:

    猜你喜欢
    • 2016-12-30
    • 2019-08-25
    • 2017-03-22
    • 2021-05-21
    • 2019-03-21
    • 2015-03-01
    • 2019-06-28
    • 2021-11-02
    • 2023-01-27
    相关资源
    最近更新 更多