/// <summary> /// Decrypts a list of elements using the cipher key. /// </summary> /// <param name="encryptedDataElems">Elements to decrypt.</param> /// <param name="cipherKey">Cipher key.</param> public void Decrypt(IList <XmlElement> encryptedDataElems, byte[] cipherKey) { ArgumentUtils.CheckNotNullNorEmpty(encryptedDataElems, "encryptedDataElems"); ArgumentUtils.CheckNotNull(cipherKey, "cipherKey"); // Decrypt the encrypted key RijndaelManaged sessionKey = new RijndaelManaged(); sessionKey.Key = cipherKey; // Decrypt each of the encrypted data elements using the decrypted key foreach (XmlElement encryptedDataElem in encryptedDataElems) { // Decrypt the data byte[] decryptedData = XmlSecurityUtils.Decrypt(encryptedDataElem, sessionKey); XmlDocument containerDoc = encryptedDataElem.OwnerDocument; // Replace the encrypted data with the decrypted data within the container EncryptedXml encryptedXml = new EncryptedXml(containerDoc); encryptedXml.ReplaceData(encryptedDataElem, decryptedData); } }
/// <summary> /// Decrypts a list of elements. /// </summary> /// <param name="encryptedKeyElems">List of encrypted key elements.</param> /// <param name="encryptedDataElems">List of encrypted data elements.</param> /// <param name="certificate">Certificate to use for key decryption.</param> public void Decrypt(IList <XmlElement> encryptedKeyElems, IList <XmlElement> encryptedDataElems, X509Certificate2 certificate) { ArgumentUtils.CheckNotNullNorEmpty(encryptedKeyElems, "encryptedKeyElems"); ArgumentUtils.CheckNotNullNorEmpty(encryptedDataElems, "encryptedDataElems"); ArgumentUtils.CheckNotNull(certificate, "certificate"); // Check the certificate has a private key if (certificate.PrivateKey == null) { throw new XspException("Certificate with subject '" + certificate.Subject + "' does not contain a private key"); } XmlDocument containerDoc = encryptedKeyElems[0].OwnerDocument; // Check the 'encryptedKeyElems' elements foreach (XmlElement encryptedKeyElem in encryptedKeyElems) { // Check they are all 'xenc:EncryptedKey' elements if (!XmlUtils.CheckElement(encryptedKeyElem, EncryptedKeyTag, EncryptedXml.XmlEncNamespaceUrl)) { throw new XspException("Element within the keys list is not " + "an 'xenc:EncryptedKey'"); } // Check they all belong to the same document if (encryptedKeyElem.OwnerDocument != containerDoc) { throw new XspException("All 'xenc:EncryptedKey' elements " + "must belong to the same document"); } } // Check the 'encryptedDataElems' elements foreach (XmlElement encryptedDataElem in encryptedDataElems) { // Check they are all 'xenc:EncryptedData' elements if (!XmlUtils.CheckElement(encryptedDataElem, EncryptedDataTag, EncryptedXml.XmlEncNamespaceUrl)) { throw new XspException("Element within the encrypted data list is " + "not an 'xenc:EncryptedData' element."); } // Check they all belong to the same document if (encryptedDataElem.OwnerDocument != containerDoc) { throw new XspException("All 'xenc:EncryptedData' elements " + "must belong to the same document"); } } // Attempt to find the matching encrypted key for the certificate EncryptedKey encryptedKey = null; foreach (XmlElement encryptedKeyElem in encryptedKeyElems) { EncryptedKey currentEncryptedKey = new EncryptedKey(); currentEncryptedKey.LoadXml(encryptedKeyElem); // Check if the subject key identifier specified within the // 'KeyInfo' of the encrypted key matches the certificate if (MatchesCertificate(currentEncryptedKey, certificate)) { encryptedKey = currentEncryptedKey; break; } } // Check if a key was found if (encryptedKey == null) { throw new KeyMismatchException( "Could not find a matching encrypted key for certificate '" + certificate.Subject + "'."); } // Decrypt the encrypted key RijndaelManaged sessionKey = new RijndaelManaged(); sessionKey.Key = XmlSecurityUtils.DecryptEncryptedKey( encryptedKey, certificate.PrivateKey); // Decrypt each of the encrypted data elements using the decrypted key foreach (XmlElement encryptedDataElem in encryptedDataElems) { // Decrypt the data byte[] decryptedData = XmlSecurityUtils.Decrypt( encryptedDataElem, sessionKey); // Replace the encrypted data with the decrypted data within the container EncryptedXml encryptedXml = new EncryptedXml(containerDoc); encryptedXml.ReplaceData(encryptedDataElem, decryptedData); } }