Чтобы проверить JWS с SubtleCrypto, вы должны быть осторожны, чтобы правильно кодировать и декодировать данные между двоичным представлением и представлением base64url. К сожалению, стандартная реализация в браузере btoa()
и atob()
трудна для работы, так как они используют строку Unicode, содержащую только символы в диапазоне от U + 0000 до U + 00FF, каждый из которых представляет собой двоичный байт со значениями от 0x00 до 0xFF соответственно "как представление двоичных данных.
Лучшее решение для представления двоичных данных в Javascript - это использовать объект ES6 TypedArray
и использовать библиотеку Javascript (или написать кодировщик самостоятельно) для преобразования их в base64url, который учитывает RFC 4648 .
Примечание: разница между base64 и base64url заключается в символах, выбранных для значений 62 и 63 в стандарте, base64 кодирует их в +
и /
, а base64url кодирует -
и _
.
Примером такой библиотеки в Javascript является rfc4648.js .
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'))
)
}