Skip to content

Commit

Permalink
feat: add RSA-OAEP-384 and RSA-OAEP-512 JWE Key Management Algorithms
Browse files Browse the repository at this point in the history
These are registered for JOSE by W3C Web Cryptography Working Group in
[Web Cryptography API](https://www.w3.org/TR/WebCryptoAPI/)
  • Loading branch information
panva committed Feb 13, 2020
1 parent b92079c commit 7477f08
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 12 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ jose.JWE.decrypt(
| AES || A128KW<sup>[1]</sup>, A192KW<sup>[1]</sup>, A256KW<sup>[1]</sup> |
| AES GCM || A128GCMKW, A192GCMKW, A256GCMKW |
| Direct Key Agreement || dir |
| RSAES OAEP || RSA-OAEP, RSA-OAEP-256<sup>[3]</sup> |
| RSAES OAEP || RSA-OAEP, RSA-OAEP-256<sup>[3]</sup>, RSA-OAEP-384<sup>[3]</sup>, RSA-OAEP-512<sup>[3]</sup> |
| RSAES-PKCS1-v1_5 || RSA1_5 |
| PBES2 || PBES2-HS256+A128KW<sup>[1]</sup>, PBES2-HS384+A192KW<sup>[1]</sup>, PBES2-HS512+A256KW<sup>[1]</sup> |
| ECDH-ES (for all EC keys) || ECDH-ES, ECDH-ES+A128KW<sup>[1]</sup>, ECDH-ES+A192KW<sup>[1]</sup>, ECDH-ES+A256KW<sup>[1]</sup> |
Expand Down Expand Up @@ -330,7 +330,7 @@ Legend:
<sup>2</sup> Unsecured JWS is [supported][documentation-none] for the JWS and JWT sign and verify
operations but it is an entirely opt-in behaviour, downgrade attacks are prevented by the required
use of a special `JWK.Key`-like object that cannot be instantiated through the key import API
<sup>3</sup> RSA-OAEP-256 is only supported when Node.js >= 12.9.0 runtime is detected
<sup>3</sup> RSAES OAEP using SHA-2 and MGF1 with SHA-2 is only supported when Node.js >= 12.9.0 runtime is detected

## FAQ

Expand Down
18 changes: 13 additions & 5 deletions lib/jwa/rsaes.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ const { asInput } = require('../help/key_object')

const resolvePadding = (alg) => {
switch (alg) {
case 'RSA-OAEP-256':
case 'RSA-OAEP':
case 'RSA-OAEP-256':
case 'RSA-OAEP-384':
case 'RSA-OAEP-512':
return constants.RSA_PKCS1_OAEP_PADDING
case 'RSA1_5':
return constants.RSA_PKCS1_PADDING
Expand All @@ -16,10 +18,14 @@ const resolvePadding = (alg) => {

const resolveOaepHash = (alg) => {
switch (alg) {
case 'RSA-OAEP-256':
return 'sha256'
case 'RSA-OAEP':
return 'sha1'
case 'RSA-OAEP-256':
return 'sha256'
case 'RSA-OAEP-384':
return 'sha384'
case 'RSA-OAEP-512':
return 'sha512'
default:
return undefined
}
Expand All @@ -38,14 +44,16 @@ const unwrapKey = (padding, oaepHash, { [KEYOBJECT]: keyObject }, payload) => {
const LENGTHS = {
RSA1_5: 0,
'RSA-OAEP': 592,
'RSA-OAEP-256': 784
'RSA-OAEP-256': 784,
'RSA-OAEP-384': 1040,
'RSA-OAEP-512': 1296
}

module.exports = (JWA, JWK) => {
const algs = ['RSA-OAEP', 'RSA1_5']

if (oaepHashSupported) {
algs.splice(1, 0, 'RSA-OAEP-256')
algs.splice(1, 0, 'RSA-OAEP-256', 'RSA-OAEP-384', 'RSA-OAEP-512')
}

algs.forEach((jwaAlg) => {
Expand Down
30 changes: 25 additions & 5 deletions test/jwk/rsa.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ test('RSA key .algorithms invalid operation', t => {
test('RSA Private key algorithms (no operation)', t => {
const result = key.algorithms()
t.is(result.constructor, Set)
t.deepEqual([...result], ['PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512', 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'])
t.deepEqual([...result], ['PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512', 'RSA-OAEP', 'RSA-OAEP-256', 'RSA-OAEP-384', 'RSA-OAEP-512', 'RSA1_5'])
})
} else {
test('RSA Private key algorithms (no operation)', t => {
Expand Down Expand Up @@ -129,7 +129,7 @@ test('RSA key .algorithms invalid operation', t => {
test('RSA Private key .algorithms("wrapKey")', t => {
const result = key.algorithms('wrapKey')
t.is(result.constructor, Set)
t.deepEqual([...result], ['RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'])
t.deepEqual([...result], ['RSA-OAEP', 'RSA-OAEP-256', 'RSA-OAEP-384', 'RSA-OAEP-512', 'RSA1_5'])
})
} else {
test('RSA Private key .algorithms("wrapKey")', t => {
Expand All @@ -150,7 +150,7 @@ test('RSA key .algorithms invalid operation', t => {
test('RSA Private key .algorithms("unwrapKey")', t => {
const result = key.algorithms('unwrapKey')
t.is(result.constructor, Set)
t.deepEqual([...result], ['RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'])
t.deepEqual([...result], ['RSA-OAEP', 'RSA-OAEP-256', 'RSA-OAEP-384', 'RSA-OAEP-512', 'RSA1_5'])
})
} else {
test('RSA Private key .algorithms("unwrapKey")', t => {
Expand Down Expand Up @@ -192,7 +192,7 @@ test('RSA key .algorithms invalid operation', t => {
test('RSA EC Public key algorithms (no operation)', t => {
const result = key.algorithms()
t.is(result.constructor, Set)
t.deepEqual([...result], ['PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512', 'RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'])
t.deepEqual([...result], ['PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512', 'RSA-OAEP', 'RSA-OAEP-256', 'RSA-OAEP-384', 'RSA-OAEP-512', 'RSA1_5'])
})
} else {
test('RSA EC Public key algorithms (no operation)', t => {
Expand Down Expand Up @@ -285,7 +285,7 @@ test('RSA key .algorithms invalid operation', t => {
test('RSA Public key .algorithms("wrapKey")', t => {
const result = key.algorithms('wrapKey')
t.is(result.constructor, Set)
t.deepEqual([...result], ['RSA-OAEP', 'RSA-OAEP-256', 'RSA1_5'])
t.deepEqual([...result], ['RSA-OAEP', 'RSA-OAEP-256', 'RSA-OAEP-384', 'RSA-OAEP-512', 'RSA1_5'])
})
} else {
test('RSA Public key .algorithms("wrapKey")', t => {
Expand Down Expand Up @@ -341,6 +341,16 @@ test('RSA key .algorithms invalid operation', t => {
const k = generateSync('RSA', 784)
t.true(k.algorithms().has('RSA-OAEP-256'))
})

test('RSA key >= 1040 bits can do RSA-OAEP-256', t => {
const k = generateSync('RSA', 1040)
t.true(k.algorithms().has('RSA-OAEP-384'))
})

test('RSA key >= 1296 bits can do RSA-OAEP-256', t => {
const k = generateSync('RSA', 1296)
t.true(k.algorithms().has('RSA-OAEP-512'))
})
}

test('RSA key >= 784 bits can do PS384', t => {
Expand Down Expand Up @@ -375,6 +385,16 @@ test('RSA key .algorithms invalid operation', t => {
const k = generateSync('RSA', 896)
t.true(k.algorithms().has('RSA-OAEP-256'))
})

test('RSA key >= 1040 bits can do RSA-OAEP-256', t => {
const k = generateSync('RSA', 1152)
t.true(k.algorithms().has('RSA-OAEP-384'))
})

test('RSA key >= 1408 bits can do RSA-OAEP-256', t => {
const k = generateSync('RSA', 1408)
t.true(k.algorithms().has('RSA-OAEP-512'))
})
}

test('RSA key >= 1152 bits can do PS512', t => {
Expand Down

0 comments on commit 7477f08

Please sign in to comment.