// Try to decrypt the EncryptedKey given the key mapping public virtual byte[] DecryptEncryptedKey(EncryptedKey encryptedKey) { if (encryptedKey == null) { throw new ArgumentNullException("encryptedKey"); } if (encryptedKey.KeyInfo == null) { return(null); } IEnumerator keyInfoEnum = encryptedKey.KeyInfo.GetEnumerator(); KeyInfoName kiName; KeyInfoX509Data kiX509Data; KeyInfoRetrievalMethod kiRetrievalMethod; KeyInfoEncryptedKey kiEncKey; EncryptedKey ek = null; bool fOAEP = false; while (keyInfoEnum.MoveNext()) { kiName = keyInfoEnum.Current as KeyInfoName; if (kiName != null) { // Get the decryption key from the key mapping string keyName = kiName.Value; Object kek = m_keyNameMapping[keyName]; if (kek != null) { // kek is either a SymmetricAlgorithm or an RSA key, otherwise, we wouldn't be able to insert it in the hash table if (kek is SymmetricAlgorithm) { return(EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, (SymmetricAlgorithm)kek)); } // kek is an RSA key: get fOAEP from the algorithm, default to false fOAEP = (encryptedKey.EncryptionMethod != null && encryptedKey.EncryptionMethod.KeyAlgorithm == EncryptedXml.XmlEncRSAOAEPUrl); return(EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, (RSA)kek, fOAEP)); } break; } kiX509Data = keyInfoEnum.Current as KeyInfoX509Data; if (kiX509Data != null) { X509CertificateCollection collection = Utils.BuildBagOfCerts(kiX509Data, CertUsageType.Decryption); foreach (X509Certificate certificate in collection) { RSA privateKey = certificate.PrivateKey as RSA; if (privateKey != null) { fOAEP = (encryptedKey.EncryptionMethod != null && encryptedKey.EncryptionMethod.KeyAlgorithm == EncryptedXml.XmlEncRSAOAEPUrl); return(EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, privateKey, fOAEP)); } } break; } kiRetrievalMethod = keyInfoEnum.Current as KeyInfoRetrievalMethod; if (kiRetrievalMethod != null) { string idref = Utils.ExtractIdFromLocalUri(kiRetrievalMethod.Uri); ek = new EncryptedKey(); ek.LoadXml(GetIdElement(m_document, idref)); return(DecryptEncryptedKey(ek)); } kiEncKey = keyInfoEnum.Current as KeyInfoEncryptedKey; if (kiEncKey != null) { ek = kiEncKey.EncryptedKey; // recursively process EncryptedKey elements byte[] encryptionKey = DecryptEncryptedKey(ek); if (encryptionKey != null) { // this is a symmetric algorithm for sure SymmetricAlgorithm symAlg = (SymmetricAlgorithm)GostCryptoConfig.CreateFromName(encryptedKey.EncryptionMethod.KeyAlgorithm); symAlg.Key = encryptionKey; return(EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, symAlg)); } } } return(null); }
/// <summary> /// Расшифровывает сессионный ключ с помощью указанного асимметричного ключа RSA. /// </summary> /// <param name="keyData">Массив байт, содержащий зашифрованный сессионный ключ.</param> /// <param name="privateKey">Закрытый ключ RSA для расшифровки сессионного ключа.</param> /// <param name="useOaep">Значение, указывающее, следует ли использовать заполнение OAEP (Optimal Asymmetric Encryption Padding).</param> /// <returns>Массив байт, который содержит сессионный ключ.</returns> /// <remarks>Как правило сессионный ключ используется для шифрования данных и в свою очередь так же шифруется.</remarks> public static byte[] DecryptKey(byte[] keyData, RSA privateKey, bool useOaep) { return(EncryptedXml.DecryptKey(keyData, privateKey, useOaep)); }