Giter Site home page Giter Site logo

node-jwa's Issues

Signature is generated differently on Node v4 and Node v6

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.

Error: PEM_read_bio_PUBKEY failed

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?

base64url versus base64-url

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?

Can't resolve 'crypto'

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 ๐Ÿ˜ข

error:0409806E:rsa routines:RSA_padding_add_PKCS1_PSS_mgf1:data too large for key size

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

module ignores b64 in the header

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

Deprecating jwa and jws packages

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".

build error while using jsonwebtokens in Angular6

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'

Using RS512 algorithm with EC512 key-pair works

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

Strange algorithms are accepted

>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)

Enhancement/ tech debt: use Node's built-in toString(base64url)

Describe the problem you'd like to have solved

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).

Describe the ideal solution

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

Wrong curve used in Makefile

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.

use ECDSA with SHA256 signers and verifiers for elliptic curve algorithms

Please correct me if I'm wrong here, but I've noticed two things that together seem strange:

  1. The RSA-SHAxxx hash functions are being used to create the signers and verifiers in createKeySigner and createKeyVerifier.
  2. createECDSASigner and createECDSAVerifer are simply wrappers around createKeySigner and createKeyVerifier, with a single modification to reformat the signature

This 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;
  };
}

Handle RSA passphrase

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.