Skip to content

Commit

Permalink
Support passphrase protected keys (#117)
Browse files Browse the repository at this point in the history
* Added password protected keys for testing and updated generator script

* Added unit test for the pp key

* Updated key type checks in signer

* chore: Fixed linting issues

* Updated key handling in signer;
Updated privateKeyMatcher in crypto;
Added tests

* Fixed tests for Node v10

* Updated readme with details about the new key type

* Removed support for node v10, added v16 and v17 to the CI

* Update .github/workflows/ci.yml

* Replaced deprecated test methods;
Addressed PR comments

* Update README.md

Co-authored-by: Shogun <[email protected]>

* Update README.md

Co-authored-by: Shogun <[email protected]>

Co-authored-by: Simone Busoli <[email protected]>
Co-authored-by: Shogun <[email protected]>
  • Loading branch information
3 people authored Oct 29, 2021
1 parent 6ab7fe7 commit dddd103
Show file tree
Hide file tree
Showing 13 changed files with 262 additions and 130 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [10.x, 12.x, 14.x]
node-version: [12, 14, 16, 17]
steps:
- name: Checkout
uses: actions/[email protected]
Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ npm install fast-jwt

Create a signer function by calling `createSigner` and providing one or more of the following options:

- `key`: A string or a buffer containing the secret for `HS*` algorithms or the PEM encoded public key for `RS*`, `PS*`, `ES*` and `EdDSA` algorithms. The key can also be a function accepting a Node style callback or a function returning a promise. This is the only mandatory option. This is the only mandatory option, which must NOT be provided if the token algorithm is `none`.
- `key`: A string or a buffer containing the secret for `HS*` algorithms, the PEM encoded public key for `RS*`, `PS*`, `ES*` and `EdDSA` algorithms or it can be an object containing passphrase protected private key (more details below). The key can also be a function accepting a Node style callback or a function returning a promise. This is the only mandatory option, which must NOT be provided if the token algorithm is `none`.
- `algorithm`: The algorithm to use to sign the token. The default is autodetected from the key, using `RS256` for RSA private keys, `HS256` for plain secrets and the correspondent `ES` or `EdDSA` algorithms for EC or Ed\* private keys.
- `mutatePayload`: If the original payload must be modified in place (via `Object.assign`) and thus will result changed to the caller funciton.
- `expiresIn`: Time span (in milliseconds) after which the token expires, added as the `exp` claim in the payload. This will override any existing value in the claim.
Expand All @@ -42,6 +42,14 @@ The payload must be an object.

If the `key` option is a function, the signer will also accept a Node style callback and will return a promise, supporting therefore both callback and async/await styles.

If the `key` is a passphrase protected private key, then it must be an object with the following structure:
```js
{
key: '<YOUR_RSA_ENCRYPTED_PRIVATE_KEY>',
passphrase: '<PASSPHRASE_THAT_WAS_USED_TO_ENCRYPT_THE_PRIVATE_KEY>'
}
```

#### Example

```javascript
Expand All @@ -66,6 +74,14 @@ async function test() {
const token = await signWithPromise({ a: 1, b: 2, c: 3 })
// => eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhIjoxLCJiIjoyLCJjIjozLCJpYXQiOjE1Nzk1MjEyMTJ9.mIcxteEVjbh2MnKQ3EQlojZojGSyA_guqRBYHQURcfnCSSBTT2OShF8lo9_ogjAv-5oECgmCur_cDWB7x3X53g
}

// Using password protected private key
const signSync = createSigner({
key: {
key: '<YOUR_RSA_ENCRYPTED_PRIVATE_KEY>',
passphrase: '<PASSPHRASE_THAT_WAS_USED_TO_ENCRYPT_THE_PRIVATE_KEY>'
})
const token = signSync({ a: 1, b: 2, c: 3 })
```
### createDecoder
Expand Down
7 changes: 6 additions & 1 deletion benchmarks/keys/generate-keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ const { generateKeyPair } = require('crypto')
const { writeFileSync } = require('fs')
const { resolve } = require('path')

const passProtectedKeyPassphrase = 'secret'
const configurations = {
es: { 256: 'prime256v1', 384: 'secp384r1', 512: 'secp521r1' },
rs: { 512: null },
pprs: { 512: null },
ps: { 512: null },
ed: { 25519: null, 448: null }
}
Expand Down Expand Up @@ -38,6 +40,7 @@ for (const [prefix, configuration] of Object.entries(configurations)) {
}
} else {
for (const [bits, namedCurve] of Object.entries(configuration)) {
const isPasswordProtectedPrivateKey = prefix === 'pprs'
let type = 'pkcs8'
let format = 'pem'

Expand All @@ -60,7 +63,9 @@ for (const [prefix, configuration] of Object.entries(configurations)) {
},
privateKeyEncoding: {
type,
format
format,
cipher: isPasswordProtectedPrivateKey ? 'aes-256-cbc' : undefined,
passphrase: isPasswordProtectedPrivateKey ? passProtectedKeyPassphrase : undefined
}
},
(err, publicKey, privateKey) => {
Expand Down
54 changes: 54 additions & 0 deletions benchmarks/keys/pprs-512-private.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
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
-----END ENCRYPTED PRIVATE KEY-----
14 changes: 14 additions & 0 deletions benchmarks/keys/pprs-512-public.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvOnLWomPr6gAkw/XlfrV
xDR5VKwNawoMv/+TuTMxs3qHgEDcurW2NZZIv1JP66naSQ4YTbqAiKERVWC7UFnp
ufu9I1ZN3DbQcyF39doLl0cy3zEynqbLNqfubRVMGni4mzmOO2XKgYpoObyy8Txm
5RK2jj1iB2OFxsvOT1+F3ig5eInepfWfhEn3wviUR4d5jpS6D/vUdXsN+6XWKiDw
/3BNpi8uTApNMNI6cKGKSV5jO4QELdYytDGN2/wt9GOAd9jKza42rlpcE7UcaSWx
FEg9rFiojdQnOp3bh3SJVkiirVQR28ViNUi7X7rI15KheS6MyhxNIt+A2aeBJ1am
zH5YEhrrzeVYMZ4rvOEDQZ3twjp2uWdoNbxMe2th+wODSV5YLFddbNVrcZOyD2/C
hijVHbjrpLXqFMzjl06d8IS7+uIsTWnwysFHxYFrLA9t4DHECtaq1TuM+nY6NP4m
M0Dqf8KbSdkkBm6wmo6Ly4LsC6t5Sm33RuaPSt96TmghWvRfJiqttBjIoyk37ife
XpuilIp5dAutLMfcYRG3sDopRPJTou1AbqtS9xRzKHgo2a0ikzSNutiu+z2hlgRr
TdzxlaixBfqBNFBj6YZkI+OREnAeg98uoXUcdfCSrU83+BU888GLL/qIU8mMmvln
d8fYnS1P/u66gXdxUCPnIN8CAwEAAQ==
-----END PUBLIC KEY-----
5 changes: 3 additions & 2 deletions src/crypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const useNewCrypto = typeof directSign === 'function'
const base64UrlMatcher = /[=+/]/g
const encoderMap = { '=': '', '+': '-', '/': '_' }

const privateKeyPemMatcher = /^-----BEGIN(?: (RSA|EC))? PRIVATE KEY-----/
const privateKeyPemMatcher = /^-----BEGIN(?: (RSA|EC|ENCRYPTED))? PRIVATE KEY-----/
const publicKeyPemMatcher = '-----BEGIN PUBLIC KEY-----'
const privateKeysCache = new Cache(1000)
const publicKeysCache = new Cache(1000)
Expand Down Expand Up @@ -116,7 +116,8 @@ function performDetectPrivateKeyAlgoritm(key) {
let curveId

switch (pemData[1]) {
case 'RSA': // pkcs1 format - Can only be a RSA key
case 'RSA': // pkcs1 format - Can only be RSA or an ENCRYPTED (RSA) key
case 'ENCRYPTED':
return 'RS256'
case 'EC': // sec1 format - Can only be a EC key
keyData = ECPrivateKey.decode(key, 'pem', { label: 'EC PRIVATE KEY' })
Expand Down
7 changes: 4 additions & 3 deletions src/signer.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ module.exports = function createSigner(options) {
}

const keyType = typeof key
const isKeyPasswordProtected = (keyType === 'object') && key && key.key && key.passphrase

if (algorithm === 'none') {
if (key) {
Expand All @@ -213,17 +214,17 @@ module.exports = function createSigner(options) {
'The key option must not be provided when the algorithm option is "none".'
)
}
} else if (!key || (keyType !== 'string' && !(key instanceof Buffer) && keyType !== 'function')) {
} else if (!key || (keyType !== 'string' && !(key instanceof Buffer) && keyType !== 'function' && !isKeyPasswordProtected)) {
throw new TokenError(
TokenError.codes.invalidOption,
'The key option must be a string, a buffer or a function returning the algorithm secret or private key.'
'The key option must be a string, a buffer, an object containing key/passphrase properties or a function returning the algorithm secret or private key.'
)
}

// Convert the key to a string when not a function, in order to be able to detect
if (key && keyType !== 'function') {
// Detect the private key - If the algorithm was known, just verify they match, otherwise assign it
const availableAlgorithm = detectPrivateKeyAlgorithm(key)
const availableAlgorithm = detectPrivateKeyAlgorithm(isKeyPasswordProtected ? key.key : key)

if (algorithm) {
checkIsCompatibleAlgorithm(algorithm, availableAlgorithm)
Expand Down
8 changes: 4 additions & 4 deletions test/compatibility.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ for (const type of ['HS', 'ES', 'RS', 'PS']) {
const verify = createVerifier({ algorithm, key: publicKey.toString() })
const token = jsonwebtokenSign({ a: 1, b: 2, c: 3 }, privateKey.toString(), { algorithm, noTimestamp: true })

t.strictDeepEqual(verify(token), { a: 1, b: 2, c: 3 })
t.strictSame(verify(token), { a: 1, b: 2, c: 3 })

t.end()
})
Expand All @@ -53,7 +53,7 @@ for (const type of ['HS', 'ES', 'RS', 'PS']) {
const signer = createSigner({ algorithm, key: privateKey, noTimestamp: true })
const token = signer({ a: 1, b: 2, c: 3 })

t.strictDeepEqual(jsonwebtokenVerify(token, publicKey, { algorithm }), { a: 1, b: 2, c: 3 })
t.strictSame(jsonwebtokenVerify(token, publicKey, { algorithm }), { a: 1, b: 2, c: 3 })
t.end()
})
}
Expand All @@ -70,7 +70,7 @@ if (useNewCrypto) {
}
})

t.strictDeepEqual(verify(token), { a: 1, b: 2, c: 3 })
t.strictSame(verify(token), { a: 1, b: 2, c: 3 })

t.end()
})
Expand All @@ -79,7 +79,7 @@ if (useNewCrypto) {
const signer = createSigner({ key: privateKeys[curve], noTimestamp: true })
const token = signer({ a: 1, b: 2, c: 3 })

t.strictDeepEqual(joseVerify(token, asKey(publicKeys[curve])), { a: 1, b: 2, c: 3 })
t.strictSame(joseVerify(token, asKey(publicKeys[curve])), { a: 1, b: 2, c: 3 })
t.end()
})
}
Expand Down
10 changes: 5 additions & 5 deletions test/compliance.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ test('HS256', t => {

const verified = createVerifier({ key })(token)

t.deepEqual(verified, payload)
t.same(verified, payload)
t.equal(token, expectedToken)

t.end()
Expand All @@ -104,7 +104,7 @@ test('RS256', t => {

const verified = createVerifier({ key: rsaPublicKey })(token)

t.deepEqual(verified, payload)
t.same(verified, payload)
t.equal(token, expectedToken)

t.end()
Expand All @@ -123,7 +123,7 @@ test('PS384', t => {

const verified = createVerifier({ key: rsaPublicKey })(token)

t.deepEqual(verified, payload)
t.same(verified, payload)
// Since PS algorithm uses random data, we cannot match the signature
t.equal(token.replace(/\..+/, ''), expectedToken.replace(/\..+/, ''))

Expand All @@ -143,7 +143,7 @@ test('ES512', t => {

const verified = createVerifier({ key: ecPublicKey })(token)

t.deepEqual(verified, payload)
t.same(verified, payload)
// Since ES algorithm uses random data, we cannot match the signature
t.equal(token.replace(/\..+/, ''), expectedToken.replace(/\..+/, ''))

Expand Down Expand Up @@ -173,7 +173,7 @@ if (useNewCrypto) {

const verified = createVerifier({ key: ed25519PublicKey })(token)

t.deepEqual(verified, payload)
t.same(verified, payload)
t.equal(token, expectedToken)

t.end()
Expand Down
32 changes: 16 additions & 16 deletions test/crypto.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ for (const type of ['Ed25519', 'Ed448']) {
const privateKey = privateKeys[type]

test(`detectPrivateKeyAlgorithm - ${type} keys should be recognized as EdDSA`, t => {
t.strictDeepEqual(detectPrivateKeyAlgorithm(privateKey), 'EdDSA')
t.strictSame(detectPrivateKeyAlgorithm(privateKey), 'EdDSA')

t.end()
})
Expand Down Expand Up @@ -186,7 +186,7 @@ for (const type of ['HS', 'ES', 'RS', 'PS']) {
const publicKey = publicKeys[type === 'ES' ? algorithm : type]

test(`detectPublicKeyAlgorithms - ${type} keys should be recognized as ${detectedAlgorithm}`, t => {
t.strictDeepEqual(detectPublicKeyAlgorithms(publicKey), detectedAlgorithm)
t.strictSame(detectPublicKeyAlgorithms(publicKey), detectedAlgorithm)

t.end()
})
Expand All @@ -201,14 +201,14 @@ for (const type of ['Ed25519', 'Ed448']) {
const publicKey = publicKeys[type]

test(`detectPublicKeyAlgorithms - ${type} keys should be recognized as EdDSA`, t => {
t.strictDeepEqual(detectPublicKeyAlgorithms(publicKey), ['EdDSA'])
t.strictSame(detectPublicKeyAlgorithms(publicKey), ['EdDSA'])

t.end()
})
}

test('detectPublicKeyAlgorithms - empty key should return "none"', t => {
t.equals(detectPublicKeyAlgorithms(), 'none')
t.equal(detectPublicKeyAlgorithms(), 'none')

t.end()
})
Expand Down Expand Up @@ -279,8 +279,8 @@ for (const bits of [256, 384, 512]) {
const verified = createVerifier({ key: 'secretsecretsecret' })(token)

t.equal(verified.payload, 'PAYLOAD')
t.true(verified.iat >= start)
t.true(verified.iat <= Date.now() / 1000)
t.ok(verified.iat >= start)
t.ok(verified.iat <= Date.now() / 1000)

t.end()
})
Expand All @@ -293,8 +293,8 @@ for (const bits of [256, 384, 512]) {
const verified = createVerifier({ key: 'secretsecretsecret' })(token)

t.equal(verified.payload, 'PAYLOAD')
t.true(verified.iat >= start)
t.true(verified.iat <= Date.now() / 1000)
t.ok(verified.iat >= start)
t.ok(verified.iat <= Date.now() / 1000)

t.end()
})
Expand All @@ -317,8 +317,8 @@ for (const type of ['ES', 'RS', 'PS']) {
const verified = createVerifier({ key: publicKey })(token)

t.equal(verified.payload, 'PAYLOAD')
t.true(verified.iat >= start)
t.true(verified.iat <= Date.now() / 1000)
t.ok(verified.iat >= start)
t.ok(verified.iat <= Date.now() / 1000)

t.end()
})
Expand All @@ -330,8 +330,8 @@ for (const type of ['ES', 'RS', 'PS']) {
const verified = createVerifier({ algorithms: [algorithm], key: publicKey.toString('utf-8') })(token)

t.equal(verified.payload, 'PAYLOAD')
t.true(verified.iat >= start)
t.true(verified.iat <= Date.now() / 1000)
t.ok(verified.iat >= start)
t.ok(verified.iat <= Date.now() / 1000)

t.end()
})
Expand Down Expand Up @@ -367,8 +367,8 @@ if (useNewCrypto) {
const verified = createVerifier({ algorithms: ['EdDSA'], key: publicKey })(token)

t.equal(verified.payload, 'PAYLOAD')
t.true(verified.iat >= start)
t.true(verified.iat <= Date.now() / 1000)
t.ok(verified.iat >= start)
t.ok(verified.iat <= Date.now() / 1000)

t.end()
})
Expand All @@ -380,8 +380,8 @@ if (useNewCrypto) {
const verified = createVerifier({ algorithms: ['EdDSA'], key: publicKey.toString('utf-8') })(token)

t.equal(verified.payload, 'PAYLOAD')
t.true(verified.iat >= start)
t.true(verified.iat <= Date.now() / 1000)
t.ok(verified.iat >= start)
t.ok(verified.iat <= Date.now() / 1000)

t.end()
})
Expand Down
4 changes: 2 additions & 2 deletions test/decoder.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ const nonJwtToken =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVEFBIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik9LIiwiaWF0Ijo5ODc2NTQzMjEwfQ.Tauq025SLRNP4qTYsr_FHXwjQ_ZTsAjBGwE-2h6if4k'

test('should return a valid token', t => {
t.strictDeepEqual(defaultDecoder(token), { sub: '1234567890', name: 'OK', iat: 9876543210 })
t.strictSame(defaultDecoder(token), { sub: '1234567890', name: 'OK', iat: 9876543210 })

t.strictDeepEqual(completeDecoder(Buffer.from(token, 'utf-8')), {
t.strictSame(completeDecoder(Buffer.from(token, 'utf-8')), {
header: {
alg: 'HS256',
typ: 'JWT'
Expand Down
Loading

0 comments on commit dddd103

Please sign in to comment.