auth0 / node-jwa Goto Github PK
View Code? Open in Web Editor NEWJSON Web Algorithms
Home Page: http://tools.ietf.org/id/draft-ietf-jose-json-web-algorithms-08.html
License: MIT License
JSON Web Algorithms
Home Page: http://tools.ietf.org/id/draft-ietf-jose-json-web-algorithms-08.html
License: MIT License
Hello,
I'm trying to switch a project from Node v4 to Node v6, but I'm facing a little problem.
We are using node-jsonwebtoken, which use this library to sign jwt, and it seems that signatures are not generated the same way on node v4 and v6.
I've investigated the issue, I ended up here and found where it happens.
My secret and my payload look like this :
const crypto = require('crypto');
const secret = crypto.createHash('sha256').update('secret').digest('binary');
const payload = {
uid: 'test',
iat: 1455988418,
iss: 'test'
};
Then, if I generate a signature :
const jwa = require('jwa');
const algo = jwa('HS256');
const sig = algo.sign(payload, secret);
console.log(sig);
// Node v4 => "_zPq9vDP4_Ve0mTVTF_9H3NRkluQhoR4yAg8X4yqR8Q"
// Node v6 => "hk9bpxID-HOmvNpJUy7x80KqT5JP8tb_BoAJLYVIYsE"
After reading the code of this library, seems that the problem is coming from this line => https://github.com/brianloveswords/node-jwa/blob/master/index.js#L35
The signature is generated like this :
var sig = (hmac.update(thing), hmac.digest('base64'));
I went back to the crypto library, and found that crypto default encoding for digest has changed between node 4 and 6 ( nodejs/node#6813 (comment) )
I tried to change in the lib hmac.update(thing)
to hmac.update(thing, 'binary')
but it changes nothing.
By the way, the secret generated is still the same between Node 4 and Node 6.
Do you have any idea of what is happening ?
Thanks a lot for this library, and for your help :)
Have a nice day.
Hey,
I try to use https://github.com/brianloveswords/node-jws/ to generate and verify a JWT using a PEM certificate.
Here is my code:
var pem = fs.readFileSync('public/certs/key.pem');
var sign = function (data) {
return jws.sign({
header: {
alg: 'RS256',
typ: 'JWT'
},
payload: data,
secret: secretJwk()
});
};
var verify = function (signed) {
return jws.verify(signed, 'RS256', secretJwk())
};
function secretJwk() {
return pem.toString();
}
When I test it in the console, the signing works, but the verification throws an error:
$ node
> cr = require('./auth/consentRequest.js')
{ sign: [Function: sign], verify: [Function: verify] }
> signed = cr.sign({foo: "bar"})
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.UBU_OakKEMN-NhO2AfHTUMq1rsjHKc7pJxUclJX9BvI4AU_bDpe-dBbDfTmqSFE45PX8FGCXdUl5_gJtbc8OZcAWpaltDwmhQ-Z_nxDYoAq9D0fYnNjsfx8axGfTE_D8ayENmvMIK143kt-cKWO-WjFbUKvoDDwC6aQiAMaF8R1XX0SxMGqXb7w44E8xRDB2mryV-54i2JwiMA3aWzqPa5z0BPirOEnnpnSvnf1KvxsisMiHf4asRhSxDHeJXI1DCdJ4MzK7x4jooWXN5cxbH4BHMItprvdABPqqxTViaLkeKzUKBmrEYhZVJoV65LGdG1SVi-bCeZCno66WnjX0xw'
> cr.verify(signed)
Error: PEM_read_bio_PUBKEY failed
at Error (native)
at Verify.verify (crypto.js:311:23)
at Object.verify (/Users/phillipp/Work/Customer/Project/node_modules/jwa/index.js:68:21)
at Object.jwsVerify [as verify] (/Users/phillipp/Work/Customer/Project/node_modules/jws/lib/verify-stream.js:54:15)
at Object.verify (/Users/phillipp/Work/Customer/Project/auth/consentRequest.js:43:16)
at repl:1:4
at sigintHandlersWrap (vm.js:22:35)
at sigintHandlersWrap (vm.js:96:12)
at ContextifyScript.Script.runInThisContext (vm.js:21:12)
at REPLServer.defaultEval (repl.js:346:29)
>
Here is my certificate:
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAsOdk8QW1jengFToHHKWfKbqWqeQT3fws/6ninQHLiCaPug1e
McMvMv23YYFFL5mQZmDevTnhOxaY5+5mnLyzhCYrD6rrU8+biE/W5Zcv2GcSr1ij
JqtQslQwA2YHwCqdZPNyBVJRLwqCH5c/X017LZyFmfTEg1TFh87u1XB+SmL8aaLi
yl3H8fdYV3ws6AJIn9IyuKGxst6VCgRpoHw3Aif5BRY9bYYbHQpPXEkKZxNDZlZK
PD59qvFfqZ3ciyqYWOdXXbHk9H4uo3h+buWLeb9W1GN0R31027gTaZ/dlkrQUIa4
tIbMJA9U5kq4KkyFPdECAdF0CrbQm8WhNepXJwIDAQABAoIBACsu8Scc26re0oKb
/axyiZ3oHGswb+Eac+mdEOJ+065Sq3chWEMRgG4UHTXCFp99/w/eycCrZl3EMGM9
gPL15WR25MAYWwXEghUOWEkHVPiggKEpI/qGi1Zc0rOhrnascGt6OfUumP7As+7+
PswG3/DMapigdXARu35hd0/G/C0wAMLb5tlB7Zx/XRYHDhRmwywGZy2umrQU9n+Z
CibbWHreNMj8opTiDjWbO9eEJFoZOmcs1mLRNdc8iMGbuCFJROCR8heNTtS62GeQ
cXcWQV000mNBDs/CTNLTFIK/AcZ5yNn42WMFdRNPexxSzVGEfmum1lJ4HNuKC+TZ
BP8SxwECgYEA1t78KQZNhi6ICa3IshBJs823ECTZICUjsYGUTxAumKbsfbt90TQY
GYdDIkMJL6vmaJFA2vvKmqL1U9WWRfKIVb0gZbVmwX+A0HdVHyljMX+oCnolXDLt
ds/kNCJwotDCLHWpVOX1OlFFeFQBDel9oEfu/7k+JNgw5uLz9sat4ecCgYEA0sP1
t1jWcZpDFZwIexNMius8ZmRz+c/KqFEL3wmz0WY7EjMChd4EHpYLAGCFyQdyjS8n
t0Qr7mre9GYm/QZimgOVvkRayEbovTe9943Xux4f4b73z+4jzz0E8eg8gL2akrRm
me2AxBbiVoKC3KeDE/ClZM2LiwznZ/7UQrVDuMECgYEAyxMV+OPnEwEZOySOwJOa
RKAQ+uYIe1P+hv3zoEGn+EgSzMYNpFH60O3Aqjn3DaIGch+NzykXk8yd1izQCK2u
4nGLk/S89/W8Vcninj/satS+iaBlfNz5B0h14jwGfiqUyZYugnmPqh0zbgTetjpN
q9UwcWmu7P2SQjSO5FVj81MCgYAcP8efW3jioRp8uv0oAd4wgHcIAk7JHOC8zqAY
tOQ1HM6uEcg0yR0kPFgdJNLJrwXbhoZ8Odbpjcl0WHzBTSnKGtDnP6IrVdW8Bsyf
cZOIsPD1APOWGwURscwH4Gi7mK4vG57k4sBvh+GuVq/Tg2A+O/LvH92kNYaOmck5
Z7I8AQKBgEfG1J/abSonS7TJ/C7ZIm1Djk29Cj057fRbc/LdYddtV96nzvqUFlHA
wdYCTYW9JDLDVa2bJdcbCBPmgjzwiCflivZ5JRE/g+wyEWFP7ZHZrWiCBjaVgond
qiGWXZG9KRmUiB1MnYgr18MKhf8sYmQRlQPTdoJH6ESgPWZsN02J
-----END RSA PRIVATE KEY-----
Anything I do wrong?
Hi.
Reason of this proposal is described here: Shinobi #452. Please also see note here: Publish deprecation notice #6
I would suggest some dialogue from the pet skit, it is particularly confusing.
jwa
depends on base64url
. But it also depends on ecdsa-sig-formatter
, which depends on base64-url
. Would it reduce the total number of dependencies to replace base64url
with base64-url
?
Today, I upgraded my angular project and suddenly I get this error:
ERROR in ./node_modules/jwa/index.js
Module not found: Error: Can't resolve 'crypto' in '/home/.../node_modules/jwa'
I have node v11.11.0 installed and there is crypto
built-in and the old library is no longer supported. My current jwa
version is the latest (1.4.1).
I don't know If I messed something up or it's the library. Don't hate me If it's a really stupid question ๐ข
https://github.com/brianloveswords/node-jwa/blob/master/index.js#L49
The signature seems to be the wrong length.
There may be nothing weird or wrong about this and I just don't understand the underlying algorithms, but my understanding did not match up to the behavior I experienced.
From my understanding, keys as short at 512 bits should be acceptable when writing a JSON Web Token. However I've found experimentally then when signing tokens using the PS512
algorithm, if I create a public/private key pair with a length less than 1034 bits then I get the error in the title.
I'm generating my key like so:
crypto.generateKeyPair(
"rsa",
{
modulusLength: 1033,
publicKeyEncoding: {type: "pkcs1", format: "pem"},
privateKeyEncoding: {type: "pkcs8", format: "pem"}
},
async (err, pub, priv) => {
if (err) throw err;
// ... write pub and priv to a file ...
}
);
I then utilize the key like so:
jsonwebtoken.sign({
sub: user.id
}, privateKey, {
algorithm: "PS512"
}, async (err, encoded) => {
if (err) throw err;
// ... return encoded key to user ...
});
This is throwing the following error:
Error: error:0409806E:rsa routines:RSA_padding_add_PKCS1_PSS_mgf1:data too large for key size
at Sign.sign (internal/crypto/sig.js:112:29)
at Object.sign (/Users/stevenbarnett/Repos/xxx/auth/node_modules/jwa/index.js:173:45)
at jwsSign (/Users/stevenbarnett/Repos/xxx/auth/node_modules/jws/lib/sign-stream.js:32:24)
at SignStream.sign (/Users/stevenbarnett/Repos/xxx/auth/node_modules/jws/lib/sign-stream.js:58:21)
at SignStream.<anonymous> (/Users/stevenbarnett/Repos/xxx/auth/node_modules/jws/lib/sign-stream.js:46:12)
at Object.onceWrapper (events.js:421:28)
at DataStream.emit (events.js:315:20)
at DataStream.EventEmitter.emit (domain.js:485:12)
at DataStream.<anonymous> (/Users/stevenbarnett/Repos/xxx/auth/node_modules/jws/lib/data-stream.js:32:12)
at processTicksAndRejections (internal/process/task_queues.js:79:11)
If I set the modulus length to 1034 or greater, or if I change the algorithm to RS512
or PS256
, the error goes away.
I don't understand the internals of the various algorithms well enough to understand why this is the case. I had hoped to utilize a very short key in development (512 bits) and a very large key in production (4096 bits) - but when I ran into this I just grew more and more confused.
I'm posting here because the last (non-internal) line of the stack trace pointed to jwa
, but this could very well be an issue with jws
, jsonwebtoken
, or even with NodeJS itself
Hello,
I am using jws library which internally uses this module and it seems that the signature generated does not meet the specifications.
According to the standards, if I pass b64: false in the header, the signature returned should not be base64Url encoded.
After going through the code of the library, it looks like you are returning base64Url encoded signature irrespective of what is passed in the header.
https://github.com/brianloveswords/node-jwa/blob/master/index.js#L153
Would appreciate your take on this.
Thanks
I have not found the time to properly maintain these packages and @brianloveswords has also been otherwise occupied. Most updates/fixes I would want to do are in some way breaking, or involve a different API. Spending time building a different API seems largely wasteful when other seemingly great packages already exist such as @panva's jose. Seeking new maintainers seems wasteful for the same reason.
I would like to deprecate these packages in order to stop worrying about them and point users to alternatives. Don't have a date in mind, but "soon".
Hi,
After upgrade from Angular 5 to 6, I've been facing below issue while compiling.
[0] ERROR in ./node_modules/jwa/index.js
[0] Module not found: Error: Can't resolve 'crypto' in 'node_modules\jwa'
[0] ERROR in ./node_modules/jws/lib/sign-stream.js
[0] Module not found: Error: Can't resolve 'stream' in 'node_modules\jws\lib'
[0] ERROR in ./node_modules/jws/lib/verify-stream.js
[0] Module not found: Error: Can't resolve 'stream' in 'node_modules\jws\lib'
[0] ERROR in ./node_modules/jws/lib/data-stream.js
[0] Module not found: Error: Can't resolve 'stream' in 'node_modules\jws\lib'
Hi,
Maybe this is something that I don't understand in cryptography, but I've stumbled upon a strange behaviour.
I created a key pair for EC512 with the following commands:
openssl ecparam -genkey -name secp521r1 -noout -out ecdsa-p521-private.pem
openssl ec -in ecdsa-p521-private.pem -pubout -out ecdsa-p521-public.pem
Then, instead of using ECDSA as I should, I used RSA:
rsa = jwa('RS512');
signature = rsa.sign('hello', fs.readFileSync('ecdsa-p521-private.pem').toString());
rsa.verify('hello', signature, fs.readFileSync('ecdsa-p521-public.pem').toString());
And the result was true!
Is this an expected behaviour? Is it possible to use ECDSA keys for RSA and vice versa?
Thanks
Hello,
Are there any plans of supporting Ed25519?
Thanks!
Dependency base64url^2.0.0 is not secure per NSP advisory 658
Please consider updating! Thanks
>npm ls --depth=0
C:\Users\Hideki\Desktop\test
โโโ [email protected]
>node -v
v4.1.2
> var jwa=require('jwa')
undefined
> jwa
[Function: jwa]
> jwa('hs256').sign('','')
'thNnmggU2ex3L5XXeMNfxf8Wl8STcVZTxscSFEKSxa0'
> jwa('ahs256b').sign('','')
'thNnmggU2ex3L5XXeMNfxf8Wl8STcVZTxscSFEKSxa0'
> jwa('none').sign('','')
''
> jwa('anoneb').sign('','')
''
> jwa('none256').sign('','')
''
> jwa('').sign('','')
TypeError: "" is not a valid algorithm.
Supported algorithms are:
"HS256", "HS384", "HS512", "RS256", "RS384", "RS512" and "none".
at typeError (C:\Users\Hideki\Desktop\test\node_modules\jwa\index.js:15:10)
at jwa (C:\Users\Hideki\Desktop\test\node_modules\jwa\index.js:116:11)
at repl:1:1
at REPLServer.defaultEval (repl.js:164:27)
at bound (domain.js:250:14)
at REPLServer.runBound [as eval] (domain.js:263:12)
at REPLServer.<anonymous> (repl.js:393:12)
at emitOne (events.js:82:20)
at REPLServer.emit (events.js:169:7)
at REPLServer.Interface._onLine (readline.js:210:10)
Currently the code has 2 functions fromBase64
and toBase64
with custom string replacement.
Starting from (at least) Node.js 14.x base64url
is a valid parameter to the Buffer.toString
API. (I traced this by looking at the Node.js API docs per version and noting when the base64url was included as valid parameter).
The code of these functions can be rewritten to:
function toBase64(base64url) {
return Buffer.from(base64url.toString(), 'base64url').toString('base64')
}
function fromBase64(base64) {
return Buffer.from(base64.toString(), 'base64').toString('base64url')
}
...taking advantage of the built-in Buffer API
Additionally, might want to specify { "engines": { "node": ">=14.x" }}
in package.json
Hi!
I think I've spotted a mistake in your Makefile. The test keys you are generating for ES256 are using a Koblitz elliptic curve (which OpenSSL refers to as "secp256k1") as opposed to the appropriate Suite B P-256 Prime field curve (which OpenSSL refers to as "prime256v1"). I think a simple s/secp256k1/prime256v1/ should do the trick.
Please correct me if I'm wrong here, but I've noticed two things that together seem strange:
RSA-SHAxxx
hash functions are being used to create the signers and verifiers in createKeySigner
and createKeyVerifier
.createECDSASigner
and createECDSAVerifer
are simply wrappers around createKeySigner
and createKeyVerifier
, with a single modification to reformat the signatureThis leads me to believe that the signers and verifiers are performing signing and verifying with the RSA-SHAxxx
hash functions provided by Node's built-in crypto library, when they should be using ECDSA with SHA256.
Is there something I'm missing here? Is there another place where the signers and verifiers are being defined?
I came across an issue when I browserify-ed node-jsonwebtoken
and noticed that the signing wasn't working.
Thanks!
Reference code:
function createKeySigner(bits) {
return function sign(thing, privateKey) {
if (!bufferOrString(privateKey) && !(typeof privateKey === 'object'))
throw typeError(MSG_INVALID_SIGNER_KEY);
thing = normalizeInput(thing);
// Even though we are specifying "RSA" here, this works with ECDSA
// keys as well.
const signer = crypto.createSign('RSA-SHA' + bits);
const sig = (signer.update(thing), signer.sign(privateKey, 'base64'));
return base64url.fromBase64(sig);
}
}
function createKeyVerifier(bits) {
return function verify(thing, signature, publicKey) {
if (!bufferOrString(publicKey))
throw typeError(MSG_INVALID_VERIFIER_KEY);
thing = normalizeInput(thing);
signature = base64url.toBase64(signature);
const verifier = crypto.createVerify('RSA-SHA' + bits);
verifier.update(thing);
return verifier.verify(publicKey, signature, 'base64');
}
}
function createECDSASigner(bits) {
const inner = createKeySigner(bits);
return function sign() {
var signature = inner.apply(null, arguments);
signature = formatEcdsa.derToJose(signature, 'ES' + bits);
return signature;
};
}
function createECDSAVerifer(bits) {
const inner = createKeyVerifier(bits);
return function verify(thing, signature, publicKey) {
signature = formatEcdsa.joseToDer(signature, 'ES' + bits).toString('base64');
const result = inner(thing, signature, publicKey);
return result;
};
}
Hello,
I would like to use a {key : cert, passphrase: 'pass'} has key to pass on to the crypto lib for signing and using protected pem files.
Looking at the NodeJs Crypto documentation I found that this is faisable.
The only problem is that you check if the provided key is a buffer or a string. I believe this is not necessary as the lib handles it.
ERROR in ./node_modules/jwa/index.js
Module not found: Error: Can't resolve 'crypto' in 'E:\My Code\mycode\pwa\node_modules\jwa'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.