Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: review feedback
Browse files Browse the repository at this point in the history
Leonardo Zanivan committed Jan 10, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 575108f commit b4120ed
Showing 4 changed files with 18 additions and 23 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ var options = {
pem: fs.readFileSync(__dirname + '/your_public_cert.pem'),
encryptionAlgorithm: 'http://www.w3.org/2001/04/xmlenc#aes256-cbc',
keyEncryptionAlgorithm: 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p',
keyEncryptionDigest: 'sha1',
disallowEncryptionWithInsecureAlgorithm: true,
warnInsecureAlgorithm: true
};
4 changes: 2 additions & 2 deletions lib/templates/keyinfo.tpl.xml.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
var escapehtml = require('escape-html');

module.exports = ({ encryptionPublicCert, encryptedKey, keyEncryptionMethod, oaepHash }) => `
module.exports = ({ encryptionPublicCert, encryptedKey, keyEncryptionMethod, keyEncryptionDigest }) => `
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="${escapehtml(keyEncryptionMethod)}">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#${escapehtml(oaepHash)}" />
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#${escapehtml(keyEncryptionDigest)}" />
</e:EncryptionMethod>
<KeyInfo>
${encryptionPublicCert}
32 changes: 13 additions & 19 deletions lib/xmlenc.js
Original file line number Diff line number Diff line change
@@ -9,15 +9,13 @@ const insecureAlgorithms = [
//https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA
'http://www.w3.org/2001/04/xmlenc#tripledes-cbc'];

function encryptKeyInfoWithScheme(symmetricKey, options, scheme, callback) {
const padding = scheme === 'RSA-OAEP' ? crypto.constants.RSA_PKCS1_OAEP_PADDING : crypto.constants.RSA_PKCS1_PADDING;
function encryptKeyInfoWithScheme(symmetricKey, options, padding, callback) {
const symmetricKeyBuffer = Buffer.isBuffer(symmetricKey) ? symmetricKey : Buffer.from(symmetricKey, 'utf-8');
const oaepHash = options.oaepHash || 'sha1';

try {
var encrypted = crypto.publicEncrypt({
key: options.rsa_pub,
oaepHash: oaepHash,
oaepHash: padding == crypto.constants.RSA_PKCS1_OAEP_PADDING ? options.keyEncryptionDigest : undefined,
padding: padding
}, symmetricKeyBuffer);
var base64EncodedEncryptedKey = encrypted.toString('base64');
@@ -26,7 +24,7 @@ function encryptKeyInfoWithScheme(symmetricKey, options, scheme, callback) {
encryptedKey: base64EncodedEncryptedKey,
encryptionPublicCert: '<X509Data><X509Certificate>' + utils.pemToCert(options.pem.toString()) + '</X509Certificate></X509Data>',
keyEncryptionMethod: options.keyEncryptionAlgorithm,
oaepHash: oaepHash,
keyEncryptionDigest: options.keyEncryptionDigest,
};

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

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

default:
return callback(new Error('encryption key algorithm not supported'));
@@ -238,19 +237,16 @@ function decryptKeyInfo(doc, options) {
throw new Error('cant find encryption algorithm');
}

let oaepHash = 'sha1';
const keyDigestMethod = xpath.select("//*[local-name(.)='KeyInfo']/*[local-name(.)='EncryptedKey']/*[local-name(.)='EncryptionMethod']/*[local-name(.)='DigestMethod']", doc)[0];
if (keyDigestMethod) {
const keyDigestMethodAlgorithm = keyDigestMethod.getAttribute('Algorithm');

switch (keyDigestMethodAlgorithm) {
case 'http://www.w3.org/2000/09/xmldsig#sha1':
options.oaepHash = 'sha1';
break;
case 'http://www.w3.org/2000/09/xmldsig#sha256':
options.oaepHash = 'sha256';
oaepHash = 'sha256';
break;
case 'http://www.w3.org/2000/09/xmldsig#sha512':
options.oaepHash = 'sha512';
oaepHash = 'sha512';
break;
}
}
@@ -266,20 +262,18 @@ function decryptKeyInfo(doc, options) {

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

function decryptKeyInfoWithScheme(encryptedKey, options, scheme) {
const padding = scheme === 'RSA-OAEP' ? crypto.constants.RSA_PKCS1_OAEP_PADDING : crypto.constants.RSA_PKCS1_PADDING;
function decryptKeyInfoWithScheme(encryptedKey, options, padding, oaepHash) {
const key = Buffer.from(encryptedKey.textContent, 'base64');
const oaepHash = options.oaepHash || 'sha1';
const decrypted = crypto.privateDecrypt({ key: options.key, oaepHash, padding}, key);
const decrypted = crypto.privateDecrypt({ key: options.key, padding, oaepHash}, key);
return Buffer.from(decrypted, 'binary');
}

4 changes: 2 additions & 2 deletions test/xmlenc.encryptedkey.js
Original file line number Diff line number Diff line change
@@ -43,14 +43,14 @@ describe('encrypt', function() {
encryptionOptions: {
encryptionAlgorithm: 'http://www.w3.org/2009/xmlenc11#aes128-gcm',
keyEncryptionAlgorithm: 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p',
oaepHash: 'sha256'
keyEncryptionDigest: 'sha256'
}
}, {
name: 'aes-128-gcm with sha512',
encryptionOptions: {
encryptionAlgorithm: 'http://www.w3.org/2009/xmlenc11#aes128-gcm',
keyEncryptionAlgorithm: 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p',
oaepHash: 'sha512'
keyEncryptionDigest: 'sha512'
}
}, {
name: 'des-ede3-cbc',

0 comments on commit b4120ed

Please sign in to comment.