Skip to content
This repository has been archived by the owner on Apr 18, 2022. It is now read-only.

Add private/public key sign/verify method #6

Open
brandonros opened this issue May 1, 2019 · 5 comments
Open

Add private/public key sign/verify method #6

brandonros opened this issue May 1, 2019 · 5 comments

Comments

@brandonros
Copy link

Nice repo! I'm hoping it'll solve my JWT/JWS signing performance woes in my package.

Would you happen to have an example on how to sign a JWT with RS256?

return new Promise((resolve, reject) => {
  jws.createSign({
    header: { typ: 'JWT', alg: algorithm },
    privateKey: jwtKey,
    payload: payload,
  })
  .once('done', resolve)
  .once('error', reject)
})

I have this from the popular jws package. Not sure how to recreate that using your crypto instead of node's crypto.

@brandonros
Copy link
Author

brandonros commented May 1, 2019

Looks like this isn't possible because you have no support for RSA PKCS#1. Is that correct?

https://github.com/brianloveswords/node-jwa/blob/master/index.js#L151 seems to be what I'm looking to accomplish.

@jorangreef
Copy link
Collaborator

Thanks @brandonros

I'm sorry I have not added support for anything beyond AEADs, HMACs and hashes.

Does Node support RSA signing? Is it a matter of performance? There is an issue with Node I opened to improve the performance of Node's sync crypto. If it's sheer low latency you need (not necessarily throughput or hundreds of thousands of signing requests), then faster sync methods (with less C++ roundtrips like how we do it) might help you.

@brandonros
Copy link
Author

Does Node support RSA signing?

export const signJwt = (privateKey: Buffer, header: JwtHeader, payload: JwtPayload): string => {
  const securedInput = `${Buffer.from(JSON.stringify(header)).toString('base64')}.${Buffer.from(JSON.stringify(payload)).toString('base64')}`
  const signature = crypto.createSign('RSA-SHA256')
    .update(securedInput)
    .sign(privateKey)
    .toString('base64')
  return `${securedInput}.${signature}`
}

It does.

The signing I am doing is very easy. It is about ~680 bytes.

Locally on my MacBook Pro, I get 50000 RSA-SHA256 iterations took 14711.183667ms (0.29422367334ms per)

It's just that, with the way the node.js internal crypto library is set up, this blocks the event loop.

I get 10x performance if I move the crypto operation to a cluster fork() and use IPC to keep it away from express listening for requests.

@jorangreef
Copy link
Collaborator

It's just that, with the way the node.js internal crypto library is set up, this blocks the event loop.

Yes, it's critical not to block the event loop, since it's the control plane of everything else.

I get 10x performance if I move the crypto operation to a cluster fork() and use IPC to keep it away from express listening for requests.

Without the overhead of IPC and cluster, i.e. running the crypto operations directly in the threadpool from the same process, you should be able to increase that performance substantially.

I'm sorry we don't have support for signing. I hope your use-case is one more reason for Node core to get async one-shot signing methods soon.

@brandonros
Copy link
Author

Would you be open to consider supporting RSA signing? You already have the sha256 digest component from what I can tell.

It looks something like this: openssl dgst -sha256 -sign private-key.pem < data.base64 | openssl rsautl -sign -inkey -keyform PEM | base64

@jorangreef jorangreef changed the title JWT/JWS example Add private/public key sign/verify method May 9, 2019
@jorangreef jorangreef reopened this May 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants