Когда я изучал uPort, который известен своей платформой самосуверенной идентификации на Ethereum, я изо всех сил пытался создать JWT (uPort обеспечивает идентификацию вне сети с помощью JWT). Итак, отмечу свой опыт для будущего ученика.
Рабочий пример кода на Gist: jwt-secp256k1-secp256r1.js
Произошла ошибка
Мы можем использовать пару открытого / закрытого ключей ECDSA, чтобы подписать JWT как официальный сайт. Итак, я написал сценарий следующим образом. Обратите внимание, что я указываю "secp256k1" как кривую ECDSA.
const JWT = require('jsonwebtoken'); const Elliptic = require('elliptic').ec; const EC = new Elliptic('secp256k1');// Use 'secp256k1' // Payload const payload = { sub: 'Subject', iss: 'Issuer', exp: 1639248876 } // Generate private key const privateKey = EC.genKeyPair().getPrivate().toString(16); // Create token const token = JWT.sign(payload, privateKey, { algorithm: 'ES256'});
Ожидаемый результат - следующая ошибка.
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line at Sign.sign (crypto.js:331:26) at sign (/work/node_modules/jwa/index.js:76:45) at Object.sign (/work/node_modules/jwa/index.js:96:27) at Object.jwsSign [as sign] (/work/node_modules/jws/lib/sign-stream.js:32:24) at Object.module.exports [as sign] (/work/node_modules/jsonwebtoken/sign.js:188:21) at Object.<anonymous> (/work/jwt.js:24:13) at Module._compile (module.js:653:30) at Object.Module._extensions..js (module.js:664:10) at Module.load (module.js:566:32) at tryModuleLoad (module.js:506:12)
Причина: secp256k1.
У меня были проблемы с решением этой ошибки, но меня спасла эта опубликованная проблема.
Спецификация JWA определяет ES256 как ECDSA с использованием P-256 и SHA-256, где P-256 - другое имя для secp256r1.
Я понял, что для JWT доступен только secp256r1. На всякий случай подтвердил RFC и нашел следующие слова.
ECDSA с использованием кривой P-256
P-256 определяется как secp256r1.
Правильный способ создания JWT
Я показываю правильный рабочий образец для создания JWT для информации. Укажите "secp256r1" в качестве кривой ECDSA.
const JWT = require('jsonwebtoken'); const ECDSA = require('ecdsa-secp256r1');// Use 'secp256r1' // Payload const payload = { sub: 'Subject', iss: 'Issuer', exp: 1639248876 } // Genarate private key const privateKey = ECDSA.generateKey(); // Retrive public key const publicKey = privateKey.asPublic(); // Create token const token = JWT.sign(payload, privateKey.toPEM(), { algorithm: 'ES256'}); // Verify token const decoded = JWT.verify(token, publicKey.toPEM()); console.log({ privateKey: privateKey.toPEM(), publicKey: publicKey.toPEM(), token, decoded });
Получайте лучшие предложения по программному обеспечению прямо в свой почтовый ящик