Closed dtwardus closed 6 years ago
This looks like an error in OpenSSL due to an invalid certificate. Switch to H
, (e.g., HS256) is a completely different algorithm (HMAC). It doesn't use a certificate and is using it as a secret instead.
Yeah I was just trying to highlight in the simplest way that RS256 wasn't working using their code. Unfortunately Google's OAuth2 requires RSA256 so I'm stuck waiting.
This looks like an issue with the certificate (either invalid or being fed to the library wrong). I can confirm that RSA is working in jsonwebtoken
since I am using it in production in several places. I don't think the issue is in the library.
Can you provide the public key and some of the code that is failing for you? I can try to help debug.
I was having the same error show up when I was attempting to .verify() an RS256 token. The solution for me was to ensure the "secret" value (signing certificate) included proper newlines. Hope this tip helps anyone else googling PEM_read_bio.
Example:
let secret = [ '-----BEGIN CERTIFICATE-----', 'MIIDHTCCAgWgAwIBAgIJMQd2wjokT/M4MA0GCSqGSIb3DQEBCwUAMCwxKjAoBgNV', '...snip...', 'iNSEkEX8oV39Y8So20V+ogLub9dJLg3EG7AeLFa6EXp6', '-----END CERTIFICATE-----' ].join('\n');`
Be sure you use the private key to sign and public key to verify.
We have some example in tests, just in case the format is incorrect or not well loaded: https://github.com/auth0/node-jsonwebtoken/blob/master/test/rsa-public-key.tests.js You can also check the keys in the test folder.
Can confirm that this works. If you are not reading from a file but are using a string, make sure the string is
1) encoded as utf-8 with the original linebreaks preserved 2) as @ziluvatar mentioned (public for verify, private for signing)
In our case we have the following setup :
new Buffer(process.env.MY_PUBLIC_KEY, 'base64').toString('utf-8')
jwt.verify(my_token, my_decoded_public_ky, { algorithms: ['RS256']), (err, payload) => { ... });
For base64 encoding the pem private/public keys we devised the following command :
openssl base64 -in mykey.pem -out mykey_encoded.pem && echo $(<mykey_encoded.pem) | tr -d ' ' > mykey_encoded.pem
I am also experiencing this issue against 8.3.0. It seems to have something to do with whitespace at the beginning or end of the public key.
Minimal repro case:
var jwt = require('jsonwebtoken')
var PUB = `
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEh/YHlmq0l2jniPJkix84v6N5PxBs
7ixY5QC0mRL2gQntE9EfWAYDukN5ImK/t1FzGF/ui3rRtc+Xh7GpnHGT9A==
-----END PUBLIC KEY-----
`
var PRIV = `
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIMRaaakPRULvTA29+gMddkT3q3AbLVpr986wIlacGpzaoAoGCCqGSM49
AwEHoUQDQgAEh/YHlmq0l2jniPJkix84v6N5PxBs7ixY5QC0mRL2gQntE9EfWAYD
ukN5ImK/t1FzGF/ui3rRtc+Xh7GpnHGT9A==
-----END EC PRIVATE KEY-----
`
var data = {"foo": "bar"}
var tok = jwt.sign({d: data}, PRIV, {algorithm: 'ES256'})
console.log(tok)
var decoded = jwt.verify(tok, PUB, {algorithms:['ES256']})
console.log(decoded)
Error:
/srv/node_modules/jsonwebtoken/verify.js:27
if (err) throw err;
^
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
at Verify.verify (internal/crypto/sig.js:150:23)
at verify (/srv/node_modules/jwa/index.js:89:21)
at Object.verify (/srv/node_modules/jwa/index.js:106:18)
at Object.jwsVerify [as verify] (/srv/node_modules/jws/lib/verify-stream.js:54:15)
at /srv/node_modules/jsonwebtoken/verify.js:116:19
at getSecret (/srv/node_modules/jsonwebtoken/verify.js:76:14)
at Object.module.exports [as verify] (/srv/node_modules/jsonwebtoken/verify.js:80:10)
at Object.<anonymous> (/srv/test.js:25:19)
at Module._compile (internal/modules/cjs/loader.js:654:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
Keys were generated like this:
openssl ecparam -name secp256r1 -genkey -out private.pem
openssl ec -in private.pem -pubout -out public.pem
This can be worked around by:
var decoded = jwt.verify(tok, PUB.trim(), {algorithms:['ES256']})
Can confirm that this works. If you are not reading from a file but are using a string, make sure the string is
1. encoded as utf-8 with the original linebreaks preserved 2. as @ziluvatar mentioned (public for verify, private for signing)
In our case we have the following setup :
* Public key is passed into environment in a base64 encoded way. * Decoded using : `new Buffer(process.env.MY_PUBLIC_KEY, 'base64').toString('utf-8')` * JWT verification in this way : `jwt.verify(my_token, my_decoded_public_ky, { algorithms: ['RS256']), (err, payload) => { ... });`
For base64 encoding the pem private/public keys we devised the following command :
openssl base64 -in mykey.pem -out mykey_encoded.pem && echo $(<mykey_encoded.pem) | tr -d ' ' > mykey_encoded.pem
Thank you, this is exactly what i needed.
使用OpenSSL生成 RSA公钥与私钥可以解决
To generate private and public key use:
ssh-keygen -t rsa -b 4096 -m PEM -f private.key openssl rsa -in jwtRS256.key -pubout -outform PEM -out public.key.pub
Then to read jwtRS256.key file : const privateKey = fs.readFileSync('private.key') :)
Don't forget to git ignore those files! 👯
If you try to use this to generate a RS256 signature it just returns an error.
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line at Sign.sign in core crypto.js — line 329 at Object.sign in jwa/index.js — line 55 at Object.jwsSign (as sign) in jws/lib/sign-stream.js — line 23 at module.exports (as sign) in jsonwebtoken/sign.js — line 178 in this notebook — line 5 at Generator.next in core — line 0 at Generator.next in core — line 0
var jsonwebtoken = require("jsonwebtoken")
var cert = "testing";
var token = jsonwebtoken.sign({ foo: 'bar' }, cert, { algorithm: 'RS256'});
console.log(token);
Using their own code from documentation. Switch the R for an H in the algorith section and watch it work.