Skip to content

Commit 614129e

Browse files
committed
Add support for oaepHash=sha256
1 parent a08c621 commit 614129e

File tree

6 files changed

+52
-30
lines changed

6 files changed

+52
-30
lines changed

Diff for: README.md

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
[![Build Status](https://travis-ci.org/auth0/node-xml-encryption.png)](https://travis-ci.org/auth0/node-xml-encryption)
22

3-
W3C XML Encryption implementation for node.js (http://www.w3.org/TR/xmlenc-core/)
3+
W3C XML Encryption implementation for Node.js (http://www.w3.org/TR/xmlenc-core/)
44

5-
Supports node >= 12 < 18
6-
7-
node 18 not supported due to https://github.com/nodejs/node/issues/52017 for Triple DES algorithms.
5+
Node 18+ does not support Triple DES algorithms due to https://github.com/nodejs/node/issues/52017
86

97
## Usage
108

@@ -20,6 +18,7 @@ var options = {
2018
pem: fs.readFileSync(__dirname + '/your_public_cert.pem'),
2119
encryptionAlgorithm: 'http://www.w3.org/2001/04/xmlenc#aes256-cbc',
2220
keyEncryptionAlgorithm: 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p',
21+
keyEncryptionDigest: 'sha1',
2322
disallowEncryptionWithInsecureAlgorithm: true,
2423
warnInsecureAlgorithm: true
2524
};

Diff for: lib/templates/keyinfo.tpl.xml.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
var escapehtml = require('escape-html');
22

3-
module.exports = ({ encryptionPublicCert, encryptedKey, keyEncryptionMethod }) => `
3+
module.exports = ({ encryptionPublicCert, encryptedKey, keyEncryptionMethod, keyEncryptionDigest }) => `
44
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
55
<e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
66
<e:EncryptionMethod Algorithm="${escapehtml(keyEncryptionMethod)}">
7-
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
7+
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#${escapehtml(keyEncryptionDigest)}" />
88
</e:EncryptionMethod>
99
<KeyInfo>
1010
${encryptionPublicCert}

Diff for: lib/xmlenc.js

+26-11
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,22 @@ const insecureAlgorithms = [
99
//https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA
1010
'http://www.w3.org/2001/04/xmlenc#tripledes-cbc'];
1111

12-
function encryptKeyInfoWithScheme(symmetricKey, options, scheme, callback) {
13-
const padding = scheme === 'RSA-OAEP' ? crypto.constants.RSA_PKCS1_OAEP_PADDING : crypto.constants.RSA_PKCS1_PADDING;
12+
function encryptKeyInfoWithScheme(symmetricKey, options, padding, callback) {
1413
const symmetricKeyBuffer = Buffer.isBuffer(symmetricKey) ? symmetricKey : Buffer.from(symmetricKey, 'utf-8');
1514

1615
try {
1716
var encrypted = crypto.publicEncrypt({
1817
key: options.rsa_pub,
18+
oaepHash: padding == crypto.constants.RSA_PKCS1_OAEP_PADDING ? options.keyEncryptionDigest : undefined,
1919
padding: padding
2020
}, symmetricKeyBuffer);
2121
var base64EncodedEncryptedKey = encrypted.toString('base64');
2222

2323
var params = {
2424
encryptedKey: base64EncodedEncryptedKey,
2525
encryptionPublicCert: '<X509Data><X509Certificate>' + utils.pemToCert(options.pem.toString()) + '</X509Certificate></X509Data>',
26-
keyEncryptionMethod: options.keyEncryptionAlgorithm
26+
keyEncryptionMethod: options.keyEncryptionAlgorithm,
27+
keyEncryptionDigest: options.keyEncryptionDigest,
2728
};
2829

2930
var result = utils.renderTemplate('keyinfo', params);
@@ -47,13 +48,14 @@ function encryptKeyInfo(symmetricKey, options, callback) {
4748
&& insecureAlgorithms.indexOf(options.keyEncryptionAlgorithm) >= 0) {
4849
return callback(new Error('encryption algorithm ' + options.keyEncryptionAlgorithm + 'is not secure'));
4950
}
51+
options.keyEncryptionDigest = options.keyEncryptionDigest || 'sha1';
5052
switch (options.keyEncryptionAlgorithm) {
5153
case 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p':
52-
return encryptKeyInfoWithScheme(symmetricKey, options, 'RSA-OAEP', callback);
54+
return encryptKeyInfoWithScheme(symmetricKey, options, crypto.constants.RSA_PKCS1_OAEP_PADDING, callback);
5355

5456
case 'http://www.w3.org/2001/04/xmlenc#rsa-1_5':
5557
utils.warnInsecureAlgorithm(options.keyEncryptionAlgorithm, options.warnInsecureAlgorithm);
56-
return encryptKeyInfoWithScheme(symmetricKey, options, 'RSAES-PKCS1-V1_5', callback);
58+
return encryptKeyInfoWithScheme(symmetricKey, options, crypto.constants.RSA_PKCS1_PADDING, callback);
5759

5860
default:
5961
return callback(new Error('encryption key algorithm not supported'));
@@ -235,6 +237,20 @@ function decryptKeyInfo(doc, options) {
235237
throw new Error('cant find encryption algorithm');
236238
}
237239

240+
let oaepHash = 'sha1';
241+
const keyDigestMethod = xpath.select("//*[local-name(.)='KeyInfo']/*[local-name(.)='EncryptedKey']/*[local-name(.)='EncryptionMethod']/*[local-name(.)='DigestMethod']", doc)[0];
242+
if (keyDigestMethod) {
243+
const keyDigestMethodAlgorithm = keyDigestMethod.getAttribute('Algorithm');
244+
switch (keyDigestMethodAlgorithm) {
245+
case 'http://www.w3.org/2000/09/xmldsig#sha256':
246+
oaepHash = 'sha256';
247+
break;
248+
case 'http://www.w3.org/2000/09/xmldsig#sha512':
249+
oaepHash = 'sha512';
250+
break;
251+
}
252+
}
253+
238254
var keyEncryptionAlgorithm = keyEncryptionMethod.getAttribute('Algorithm');
239255
if (options.disallowDecryptionWithInsecureAlgorithm
240256
&& insecureAlgorithms.indexOf(keyEncryptionAlgorithm) >= 0) {
@@ -246,19 +262,18 @@ function decryptKeyInfo(doc, options) {
246262

247263
switch (keyEncryptionAlgorithm) {
248264
case 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p':
249-
return decryptKeyInfoWithScheme(encryptedKey, options, 'RSA-OAEP');
265+
return decryptKeyInfoWithScheme(encryptedKey, options, crypto.constants.RSA_PKCS1_OAEP_PADDING, oaepHash);
250266
case 'http://www.w3.org/2001/04/xmlenc#rsa-1_5':
251267
utils.warnInsecureAlgorithm(keyEncryptionAlgorithm, options.warnInsecureAlgorithm);
252-
return decryptKeyInfoWithScheme(encryptedKey, options, 'RSAES-PKCS1-V1_5');
268+
return decryptKeyInfoWithScheme(encryptedKey, options, crypto.constants.RSA_PKCS1_PADDING);
253269
default:
254270
throw new Error('key encryption algorithm ' + keyEncryptionAlgorithm + ' not supported');
255271
}
256272
}
257273

258-
function decryptKeyInfoWithScheme(encryptedKey, options, scheme) {
259-
var padding = scheme === 'RSA-OAEP' ? crypto.constants.RSA_PKCS1_OAEP_PADDING : crypto.constants.RSA_PKCS1_PADDING;
260-
var key = Buffer.from(encryptedKey.textContent, 'base64');
261-
var decrypted = crypto.privateDecrypt({ key: options.key, padding: padding}, key);
274+
function decryptKeyInfoWithScheme(encryptedKey, options, padding, oaepHash) {
275+
const key = Buffer.from(encryptedKey.textContent, 'base64');
276+
const decrypted = crypto.privateDecrypt({ key: options.key, padding, oaepHash}, key);
262277
return Buffer.from(decrypted, 'binary');
263278
}
264279

Diff for: package-lock.json

+2-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "xml-encryption",
3-
"version": "3.0.2",
3+
"version": "3.1.0",
44
"devDependencies": {
55
"mocha": "^7.1.2",
66
"should": "^11.2.1",
@@ -30,8 +30,5 @@
3030
],
3131
"scripts": {
3232
"test": "mocha"
33-
},
34-
"engines": {
35-
"node": ">=12 < 18"
3633
}
3734
}

Diff for: test/xmlenc.encryptedkey.js

+18-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
var assert = require('assert');
22
var fs = require('fs');
3-
var should = require('should');
43
var sinon = require('sinon');
54
var xmlenc = require('../lib');
6-
var xpath = require('xpath');
75

86
describe('encrypt', function() {
97
let consoleSpy = null;
@@ -39,6 +37,21 @@ describe('encrypt', function() {
3937
encryptionAlgorithm: 'http://www.w3.org/2009/xmlenc11#aes128-gcm',
4038
keyEncryptionAlgorithm: 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p'
4139
}
40+
},
41+
{
42+
name: 'aes-128-gcm with sha256',
43+
encryptionOptions: {
44+
encryptionAlgorithm: 'http://www.w3.org/2009/xmlenc11#aes128-gcm',
45+
keyEncryptionAlgorithm: 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p',
46+
keyEncryptionDigest: 'sha256'
47+
}
48+
}, {
49+
name: 'aes-128-gcm with sha512',
50+
encryptionOptions: {
51+
encryptionAlgorithm: 'http://www.w3.org/2009/xmlenc11#aes128-gcm',
52+
keyEncryptionAlgorithm: 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p',
53+
keyEncryptionDigest: 'sha512'
54+
}
4255
}, {
4356
name: 'des-ede3-cbc',
4457
encryptionOptions: {
@@ -72,6 +85,7 @@ describe('encrypt', function() {
7285

7386
xmlenc.encrypt(content, options, function(err, result) {
7487
xmlenc.decrypt(result, { key: fs.readFileSync(__dirname + '/test-auth0.key'), warnInsecureAlgorithm: false}, function (err, decrypted) {
88+
if (err) return done(err);
7589
assert.equal(decrypted, content);
7690
done();
7791
});
@@ -92,7 +106,7 @@ describe('encrypt', function() {
92106
assert(err);
93107
assert(!result);
94108
//should not pop up warns due to options.warnInsecureAlgorithm = false;
95-
consoleSpy.called.should.equal(false);
109+
assert.equal(consoleSpy.called, false);
96110
done();
97111
});
98112
});
@@ -222,7 +236,7 @@ describe('encrypt', function() {
222236

223237
xmlenc.encryptKeyInfo(plaintext, options, function(err, encryptedKeyInfo) {
224238
if (err) return done(err);
225-
consoleSpy.called.should.equal(true);
239+
assert.equal(consoleSpy.called, true);
226240
assert.throws(
227241
function(){xmlenc.decryptKeyInfo(
228242
encryptedKeyInfo,

0 commit comments

Comments
 (0)