首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用SubtleCrypto的SubtleCrypto验证一个签名的JWT?

如何用SubtleCrypto的SubtleCrypto验证一个签名的JWT?
EN

Stack Overflow用户
提问于 2019-01-06 14:38:59
回答 1查看 3K关注 0票数 6

我试图使用SubtleCrypto的SubtleCrypto接口验证JWT的签名。

我的代码不会验证令牌签名,而JWT.io的调试工具会验证,我也不知道为什么。以下是我的验证功能:

代码语言:javascript
复制
function verify (jwToken, jwKey) {
  const partialToken = jwToken.split('.').slice(0, 2).join('.')
  const signaturePart = jwToken.split('.')[2]
  const encoder = new TextEncoder()
  return window.crypto.subtle
    .importKey('jwk', jwKey, { 
         name: 'RSASSA-PKCS1-v1_5', 
         hash: { name: 'SHA-256' } 
       }, false, ['verify'])
    .then(publicKey =>
      window.crypto.subtle.verify(
        { name: 'RSASSA-PKCS1-v1_5' },
        publicKey,
        encoder.encode(atob(signaturePart)),
        encoder.encode(partialToken)
      ).then(isValid => alert(isValid ? 'Valid token' : 'Invalid token'))
    )
}

我希望该代码能够正常工作,并对正确签名的JWT进行积极的验证。相反,示例代码无法验证签名的令牌。对于我来说,Chrome 71的例子失败了。

我还使用来自RFC 7520的示例数据设置了一些测试

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-09 15:56:29

要用SubtleCrypto验证JWS,您需要小心地在二进制和base64url表示之间正确地编码和解码数据。不幸的是,btoa()atob()浏览器中的atob()很难使用,因为它们使用“一个Unicode字符串仅包含U+0000到U+00FF范围内的字符,每个字符分别表示一个值为0x00到0xFF的二进制字节”作为二进制数据的表示形式。

在Javascript中表示二进制数据的一个更好的解决方案是使用ES6对象TypedArray,并使用Javascript库(或者自己编写编码器)将它们转换为尊重RFC 4648的base64url。

附带注意: base64和base64url的区别在于在标准中为值62和63选择的字符,base64将它们编码为+/,而base64url编码-_

Javascript中这样一个库的一个例子是rfc4648.js

代码语言:javascript
复制
import { base64url } from 'rfc4648'

async function verify (jwsObject, jwKey) {
  const jwsSigningInput = jwsObject.split('.').slice(0, 2).join('.')
  const jwsSignature = jwsObject.split('.')[2]
  return window.crypto.subtle
    .importKey('jwk', jwKey, { 
         name: 'RSASSA-PKCS1-v1_5', 
         hash: { name: 'SHA-256' } 
       }, false, ['verify'])
    .then(key=>
      window.crypto.subtle.verify(
        { name: 'RSASSA-PKCS1-v1_5' },
        key,
        base64url.parse(jwsSignature, { loose: true }),
        new TextEncoder().encode(jwsSigningInput))
      ).then(isValid => alert(isValid ? 'Valid token' : 'Invalid token'))
    )
}
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54062583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档