diff --git a/README.md b/README.md
index 9e89a14809..424c021669 100644
--- a/README.md
+++ b/README.md
@@ -300,7 +300,7 @@ jose.JWE.decrypt(
| AES | ✓ | A128KW[1], A192KW[1], A256KW[1] |
| AES GCM | ✓ | A128GCMKW, A192GCMKW, A256GCMKW |
| Direct Key Agreement | ✓ | dir |
-| RSAES OAEP | ✓ | RSA-OAEP, RSA-OAEP-256[3] |
+| RSAES OAEP | ✓ | RSA-OAEP, RSA-OAEP-256[3], RSA-OAEP-384[3], RSA-OAEP-512[3] |
| RSAES-PKCS1-v1_5 | ✓ | RSA1_5 |
| PBES2 | ✓ | PBES2-HS256+A128KW[1], PBES2-HS384+A192KW[1], PBES2-HS512+A256KW[1] |
| ECDH-ES (for all EC keys) | ✓ | ECDH-ES, ECDH-ES+A128KW[1], ECDH-ES+A192KW[1], ECDH-ES+A256KW[1] |
@@ -330,7 +330,7 @@ Legend:
2 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
-3 RSA-OAEP-256 is only supported when Node.js >= 12.9.0 runtime is detected
+3 RSAES OAEP using SHA-2 and MGF1 with SHA-2 is only supported when Node.js >= 12.9.0 runtime is detected
## FAQ
diff --git a/lib/jwa/rsaes.js b/lib/jwa/rsaes.js
index a7277123f6..f688543ee5 100644
--- a/lib/jwa/rsaes.js
+++ b/lib/jwa/rsaes.js
@@ -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
@@ -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
}
@@ -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) => {
diff --git a/test/jwk/rsa.test.js b/test/jwk/rsa.test.js
index 43dbca9fe1..84bb21e9f6 100644
--- a/test/jwk/rsa.test.js
+++ b/test/jwk/rsa.test.js
@@ -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 => {
@@ -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 => {
@@ -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 => {
@@ -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 => {
@@ -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 => {
@@ -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 => {
@@ -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 => {