JWT 令牌签名验证 javascript

Posted

技术标签:

【中文标题】JWT 令牌签名验证 javascript【英文标题】:JWT token signature validation javascript 【发布时间】:2018-05-29 20:44:21 【问题描述】:

我正在制作一个使用 JWT 令牌连接到 Api 的 javascript 客户端。在服务器端没有问题,我可以创建令牌对其进行签名,然后验证签名,从而确保没有人篡改令牌。

但是我如何在客户端执行此操作。我可以解码 JWT 令牌并查看标头、有效负载和签名。但是我如何在客户端验证签名呢?是否有用于此的库,如何将公钥传输给客户端?

如果我不验证签名,我怎么知道令牌没有被篡改?

【问题讨论】:

【参考方案1】:

这种变通方法 cmets 是我不信任其他人编写的“库”的原因。

JWT.io 报告说,许多广泛使用的库都存在安全漏洞。

RFC 7519 明确规定应用程序必须验证令牌签名,如果其签名无效,您必须丢弃它。

【讨论】:

【参考方案2】:

如果我不在客户端验证签名,如何确保令牌确实来自服务器。?可能中间有人在换代币

签名验证并不能避免中间人攻击。即使使用有效令牌,攻击者也可以嗅探通道以捕获凭据或更改消息

使用 SSL/TLS 通道 (https)


如果我不验证签名,我怎么知道令牌没有被篡改?

TLS 受信任服务器提供的令牌可能有效。(它可能已在本地存储中更改)。您可以验证签名。此操作通常在服务器端完成(参见@sakuto 答案),但您可以在浏览器中完美完成

但是如何在客户端验证签名呢?

这些是步骤

    从受信任的服务器下载公钥 从JWT中提取签名并解码(base64url) 使用密码库验证数字签名

我建议使用 Webcrypto。在此处查看 RSA 导入密钥验证示例:https://github.com/diafygi/webcrypto-examples/blob/master/README.md#rsassa-pkcs1-v1_5

【讨论】:

SSL 如何帮助中间人攻击?如果攻击者有一个有效的证书,我会相信中间的人是服务器。另一方面,中间的人没有签署 JWT 令牌所需的私钥。如果我因此验证令牌,我会看到令牌不是来自正确的服务器。 使用 SSL/TLS 客户端/浏览器有一个信任库,其中包含接受的证书颁发机构。 攻击者无法为您的主机名提供有效证书,因为受信任的 CA 不会颁发它,如果他尝试生成假证书,那么客户端将拒绝它,因为颁发者证书不存在于信任库。 正如我在回答中所说,通过 MITM 攻击(没有 HTTPS),攻击者可以捕获来自受信任服务器的有效令牌并使用它来执行欺诈操作。 攻击者不需要更改令牌即可使用它,因为被盗令牌是有效的。对于任何身份验证系统,您都必须保护通道以避免这种情况【参考方案3】:

您通常不会在客户端进行验证,也不会在令牌上存储重要数据。在后端检查每个控制和权限。这意味着即使用户篡改了它的令牌,他也无法通过后端控制,只能在前面看到一个选项。

【讨论】:

但是,如果我不在客户端验证签名,如何确保令牌确实来自服务器。?也许中间有人正在更改令牌。如果我无法确保令牌有效,那么检查发行人有什么用。或者,也许有人正在拦截我的流量并冒充服务器。我现在信任“假”服务器,我只是将我的信用卡帐号发送给他 @Arno - 在客户端,我们通常简单地解析/解码有效负载(而不是解密)并验证令牌到期。这样做是为了避免不必要的令牌调用。篡改等的实际令牌验证应在服务器端进行。

以上是关于JWT 令牌签名验证 javascript的主要内容,如果未能解决你的问题,请参考以下文章

Microsoft 帐户 JWT 身份验证令牌如何签名?

JWT/OAuth 令牌签名验证失败

使用 java-jwt 验证访问令牌签名

如何在 Nimbus JOSE + JWT 中验证令牌签名

如何验证在 jwt.io 上使用 Keycloak 身份验证提供程序创建的 HS256 签名 JWT 令牌

为啥 openssl_verify() 无法验证我的 JWT 令牌签名?