diff --git a/lib/templates/keyinfo.tpl.xml.js b/lib/templates/keyinfo.tpl.xml.js
index b629b37..9859d5f 100644
--- a/lib/templates/keyinfo.tpl.xml.js
+++ b/lib/templates/keyinfo.tpl.xml.js
@@ -1,10 +1,22 @@
var escapehtml = require('escape-html');
-module.exports = ({ encryptionPublicCert, encryptedKey, keyEncryptionMethod, keyEncryptionDigest }) => `
+const DIGEST_ALGORITHMS = {
+ // SHA-2 was published after 2000/09/xmldsig was locked, so sha256/sha512 live under 2001/04/xmlenc.
+ 'sha1': 'http://www.w3.org/2000/09/xmldsig#sha1',
+ 'sha256': 'http://www.w3.org/2001/04/xmlenc#sha256',
+ 'sha512': 'http://www.w3.org/2001/04/xmlenc#sha512'
+};
+
+module.exports = ({ encryptionPublicCert, encryptedKey, keyEncryptionMethod, keyEncryptionDigest }) => {
+ const digestUri = DIGEST_ALGORITHMS[keyEncryptionDigest] || keyEncryptionDigest;
+
+ // RSA-1.5 doesn't hash the key, so it has no digest or DigestMethod. RSA-OAEP does.
+ const isOAEP = keyEncryptionMethod && keyEncryptionMethod.includes('rsa-oaep');
+ return `
-
+ ${isOAEP ? `` : ''}
${encryptionPublicCert}
@@ -15,4 +27,4 @@ module.exports = ({ encryptionPublicCert, encryptedKey, keyEncryptionMethod, key
`;
-
+}
\ No newline at end of file
diff --git a/lib/xmlenc.js b/lib/xmlenc.js
index 8b2bc11..50fa39e 100644
--- a/lib/xmlenc.js
+++ b/lib/xmlenc.js
@@ -255,10 +255,12 @@ function decryptKeyInfo(doc, options) {
if (keyDigestMethod) {
const keyDigestMethodAlgorithm = keyDigestMethod.getAttribute('Algorithm');
switch (keyDigestMethodAlgorithm) {
- case 'http://www.w3.org/2000/09/xmldsig#sha256':
+ case 'http://www.w3.org/2001/04/xmlenc#sha256':
+ case 'http://www.w3.org/2000/09/xmldsig#sha256': // backwards compatibility for previous wrong usage
oaepHash = 'sha256';
break;
- case 'http://www.w3.org/2000/09/xmldsig#sha512':
+ case 'http://www.w3.org/2001/04/xmlenc#sha512':
+ case 'http://www.w3.org/2000/09/xmldsig#sha512': // backwards compatibility for previous wrong usage
oaepHash = 'sha512';
break;
}
diff --git a/test/xmlenc.digest.js b/test/xmlenc.digest.js
new file mode 100644
index 0000000..4994415
--- /dev/null
+++ b/test/xmlenc.digest.js
@@ -0,0 +1,152 @@
+var assert = require('assert');
+var fs = require('fs');
+var xmlenc = require('../lib');
+var keyinfoTemplate = require('../lib/templates/keyinfo.tpl.xml');
+
+var RSA_OAEP = 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p';
+var RSA_1_5 = 'http://www.w3.org/2001/04/xmlenc#rsa-1_5';
+
+describe('keyEncryptionDigest', function () {
+
+ describe('keyinfo template DigestMethod', function () {
+ function render(overrides) {
+ return keyinfoTemplate(Object.assign({
+ encryptionPublicCert: '',
+ encryptedKey: 'ZW5jcnlwdGVkS2V5',
+ keyEncryptionMethod: RSA_OAEP,
+ keyEncryptionDigest: 'sha1'
+ }, overrides));
+ }
+
+ it('maps sha1 to the xmldsig sha1 URI', function () {
+ var xml = render({ keyEncryptionDigest: 'sha1' });
+ assert(xml.includes(''));
+ });
+
+ it('maps sha256 to the xmlenc sha256 URI', function () {
+ var xml = render({ keyEncryptionDigest: 'sha256' });
+ assert(xml.includes(''));
+ });
+
+ it('maps sha512 to the xmlenc sha512 URI', function () {
+ var xml = render({ keyEncryptionDigest: 'sha512' });
+ assert(xml.includes(''));
+ });
+
+ it('passes through an unknown digest value unchanged', function () {
+ var custom = 'http://example.org/custom#sha3-256';
+ var xml = render({ keyEncryptionDigest: custom });
+ assert(xml.includes(''));
+ });
+
+ it('does NOT include a DigestMethod for RSA-1.5', function () {
+ var xml = render({ keyEncryptionMethod: RSA_1_5, keyEncryptionDigest: 'sha256' });
+ assert(!xml.includes('