public KeyInfoEncryptedKey(EncryptedKey encryptedKey) { _encryptedKey = encryptedKey; }
public override void LoadXml(XmlElement value) { _encryptedKey = new EncryptedKey(); _encryptedKey.LoadXml(value); }
public void SetEncryptedKey(EncryptedKey value) { _encryptedKey = value; }
public override void LoadXml(XmlElement element) { _encryptedKey = new EncryptedKey(); _encryptedKey.LoadXml(element); }
// Encrypts the given element with the key name specified. A corresponding key name mapping // has to be defined before calling this method. The key name is added as // a KeyNameInfo KeyInfo to an EncryptedKey (AES session key) generated randomly. public EncryptedData Encrypt(XmlElement inputElement, string keyName) { if (inputElement == null) { throw new ArgumentNullException(nameof(inputElement)); } if (keyName == null) { throw new ArgumentNullException(nameof(keyName)); } object encryptionKey = null; if (_keyNameMapping != null) { encryptionKey = _keyNameMapping[keyName]; } if (encryptionKey == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingEncryptionKey); } // kek is either a SymmetricAlgorithm or an RSA key, otherwise, we wouldn't be able to insert it in the hash table ParametersWithIV iv = encryptionKey as ParametersWithIV; KeyParameter symKey = encryptionKey as KeyParameter; RsaKeyParameters rsa = encryptionKey as RsaKeyParameters; // Create the EncryptedData object, using an AES-256 session key by default. EncryptedData ed = new EncryptedData(); ed.Type = EncryptedXml.XmlEncElementUrl; ed.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url); // Include the key name in the EncryptedKey KeyInfo. string encryptionMethod = null; if (symKey == null && iv == null) { encryptionMethod = EncryptedXml.XmlEncRSA15Url; } else if (iv != null) { symKey = iv.Parameters as KeyParameter; } if (symKey != null) { if (symKey is DesParameters) { // CMS Triple DES Key Wrap encryptionMethod = EncryptedXml.XmlEncTripleDESKeyWrapUrl; } else { // FIPS AES Key Wrap switch (symKey.GetKey().Length * 8) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128KeyWrapUrl; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192KeyWrapUrl; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256KeyWrapUrl; break; } } } EncryptedKey ek = new EncryptedKey(); ek.EncryptionMethod = new EncryptionMethod(encryptionMethod); ek.KeyInfo.AddClause(new KeyInfoName(keyName)); // Create a random AES session key and encrypt it with the public key associated with the certificate. var keydata = Utils.GenerateRandomBlock(256 / 8); var ivdata = Utils.GenerateRandomBlock(128 / 8); var rijn = new ParametersWithIV(new KeyParameter(keydata), ivdata); ek.CipherData.CipherValue = (symKey == null ? EncryptedXml.EncryptKey(keydata, rsa, false) : EncryptedXml.EncryptKey(keydata, symKey)); // Encrypt the input element with the random session key that we've created above. KeyInfoEncryptedKey kek = new KeyInfoEncryptedKey(ek); ed.KeyInfo.AddClause(kek); ed.CipherData.CipherValue = EncryptData(inputElement, rijn, false); return(ed); }
// Try to decrypt the EncryptedKey given the key mapping public virtual byte[] DecryptEncryptedKey(EncryptedKey encryptedKey, RsaKeyParameters privateKey = null) { if (encryptedKey == null) { throw new ArgumentNullException(nameof(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 = _keyNameMapping[keyName]; if (kek != null) { if (encryptedKey.CipherData == null || encryptedKey.CipherData.CipherValue == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } // 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 KeyParameter kp) { return(EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, kp)); } else if (kek is ParametersWithIV piv) { return(EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, piv.Parameters as KeyParameter)); } // 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, (RsaKeyParameters)kek, fOAEP)); } break; } kiX509Data = keyInfoEnum.Current as KeyInfoX509Data; if (kiX509Data != null) { IList <X509Certificate> collection = Utils.BuildBagOfCerts(kiX509Data, CertUsageType.Decryption); foreach (X509Certificate certificate in collection) { if (privateKey != null) { if (encryptedKey.CipherData == null || encryptedKey.CipherData.CipherValue == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } 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(_document, idref)); try { //Following checks if XML dsig processing is in loop and within the limit defined by machine // admin or developer. Once the recursion depth crosses the defined limit it will throw exception. _xmlDsigSearchDepthCounter++; if (IsOverXmlDsigRecursionLimit()) { //Throw exception once recursion limit is hit. throw new CryptoSignedXmlRecursionException(); } else { return(DecryptEncryptedKey(ek, privateKey)); } } finally { _xmlDsigSearchDepthCounter--; } } kiEncKey = keyInfoEnum.Current as KeyInfoEncryptedKey; if (kiEncKey != null) { ek = kiEncKey.EncryptedKey; // recursively process EncryptedKey elements byte[] encryptionKey = DecryptEncryptedKey(ek, privateKey); if (encryptionKey != null) { // this is a symmetric algorithm for sure IBlockCipher blockSymAlg = CryptoHelpers.CreateFromName <IBlockCipher>(encryptedKey.EncryptionMethod.KeyAlgorithm); if (blockSymAlg == null) { IBufferedCipher bufferedSymAlg = CryptoHelpers.CreateFromName <IBufferedCipher>(encryptedKey.EncryptionMethod.KeyAlgorithm); if (bufferedSymAlg == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } } if (encryptedKey.CipherData == null || encryptedKey.CipherData.CipherValue == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } return(EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, new KeyParameter(encryptionKey))); } } } return(null); }
// default behaviour is to look for keys defined by an EncryptedKey clause // either directly or through a KeyInfoRetrievalMethod, and key names in the key mapping public virtual ICipherParameters GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri) { if (encryptedData == null) { throw new ArgumentNullException(nameof(encryptedData)); } if (encryptedData.KeyInfo == null) { return(null); } IEnumerator keyInfoEnum = encryptedData.KeyInfo.GetEnumerator(); KeyInfoRetrievalMethod kiRetrievalMethod; KeyInfoName kiName; KeyInfoEncryptedKey kiEncKey; EncryptedKey ek = null; while (keyInfoEnum.MoveNext()) { kiName = keyInfoEnum.Current as KeyInfoName; if (kiName != null) { // Get the decryption key from the key mapping string keyName = kiName.Value; if (_keyNameMapping[keyName] as ICipherParameters != null) { return((ICipherParameters)_keyNameMapping[keyName]); } // try to get it from a CarriedKeyName XmlNamespaceManager nsm = new XmlNamespaceManager(_document.NameTable); nsm.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl); XmlNodeList encryptedKeyList = _document.SelectNodes("//enc:EncryptedKey", nsm); if (encryptedKeyList != null) { foreach (XmlNode encryptedKeyNode in encryptedKeyList) { XmlElement encryptedKeyElement = encryptedKeyNode as XmlElement; EncryptedKey ek1 = new EncryptedKey(); ek1.LoadXml(encryptedKeyElement); if (ek1.CarriedKeyName == keyName && ek1.Recipient == Recipient) { ek = ek1; break; } } } break; } kiRetrievalMethod = keyInfoEnum.Current as KeyInfoRetrievalMethod; if (kiRetrievalMethod != null) { string idref = Utils.ExtractIdFromLocalUri(kiRetrievalMethod.Uri); ek = new EncryptedKey(); ek.LoadXml(GetIdElement(_document, idref)); break; } kiEncKey = keyInfoEnum.Current as KeyInfoEncryptedKey; if (kiEncKey != null) { ek = kiEncKey.EncryptedKey; break; } } // if we have an EncryptedKey, decrypt to get the symmetric key if (ek != null) { // now process the EncryptedKey, loop recursively // If the Uri is not provided by the application, try to get it from the EncryptionMethod if (symmetricAlgorithmUri == null) { if (encryptedData.EncryptionMethod == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } symmetricAlgorithmUri = encryptedData.EncryptionMethod.KeyAlgorithm; } byte[] key = DecryptEncryptedKey(ek); if (key == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingDecryptionKey); } IBufferedCipher symAlg = CryptoHelpers.CreateFromName <IBufferedCipher>(symmetricAlgorithmUri); if (symAlg == null) { throw new System.Security.Cryptography.CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } KeyParameter keyParam; if (symAlg.AlgorithmName.IndexOf("DESede", StringComparison.OrdinalIgnoreCase) >= 0) { keyParam = new DesEdeParameters(key); } else if (symAlg.AlgorithmName.IndexOf("DES", StringComparison.OrdinalIgnoreCase) >= 0) { keyParam = new DesParameters(key); } else { keyParam = new KeyParameter(key); } return(keyParam); } return(null); }
// Encrypts the given element with the key name specified. A corresponding key name mapping // has to be defined before calling this method. The key name is added as // a KeyNameInfo KeyInfo to an EncryptedKey (AES session key) generated randomly. public EncryptedData Encrypt(XmlElement inputElement, string keyName) { if (inputElement == null) { throw new ArgumentNullException("inputElement"); } if (keyName == null) { throw new ArgumentNullException("keyName"); } object encryptionKey = null; if (_keyNameMapping != null) { encryptionKey = _keyNameMapping[keyName]; } if (encryptionKey == null) { throw new CryptographicException(SR.Cryptography_Xml_MissingEncryptionKey); } // kek is either a SymmetricAlgorithm or an RSA key, otherwise, we wouldn't be able to insert it in the hash table SymmetricAlgorithm symKey = encryptionKey as SymmetricAlgorithm; RSA rsa = encryptionKey as RSA; // Create the EncryptedData object, using an AES-256 session key by default. EncryptedData ed = new EncryptedData(); ed.Type = EncryptedXml.XmlEncElementUrl; ed.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url); // Include the key name in the EncryptedKey KeyInfo. string encryptionMethod = null; if (symKey == null) { encryptionMethod = EncryptedXml.XmlEncRSA15Url; } else if (symKey is TripleDES) { // CMS Triple DES Key Wrap encryptionMethod = EncryptedXml.XmlEncTripleDESKeyWrapUrl; } else if (symKey is Rijndael || symKey is Aes) { // FIPS AES Key Wrap switch (symKey.KeySize) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128KeyWrapUrl; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192KeyWrapUrl; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256KeyWrapUrl; break; } } else { // throw an exception if the transform is not in the previous categories throw new CryptographicException(SR.Cryptography_Xml_NotSupportedCryptographicTransform); } EncryptedKey ek = new EncryptedKey(); ek.EncryptionMethod = new EncryptionMethod(encryptionMethod); ek.KeyInfo.AddClause(new KeyInfoName(keyName)); // Create a random AES session key and encrypt it with the public key associated with the certificate. RijndaelManaged rijn = new RijndaelManaged(); ek.CipherData.CipherValue = (symKey == null ? EncryptedXml.EncryptKey(rijn.Key, rsa, false) : EncryptedXml.EncryptKey(rijn.Key, symKey)); // Encrypt the input element with the random session key that we've created above. KeyInfoEncryptedKey kek = new KeyInfoEncryptedKey(ek); ed.KeyInfo.AddClause(kek); ed.CipherData.CipherValue = EncryptData(inputElement, rijn, false); return(ed); }
// default behaviour is to look for keys defined by an EncryptedKey clause // either directly or through a KeyInfoRetrievalMethod, and key names in the key mapping public virtual SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri) { if (encryptedData == null) { throw new ArgumentNullException("encryptedData"); } if (encryptedData.KeyInfo == null) { return(null); } IEnumerator keyInfoEnum = encryptedData.KeyInfo.GetEnumerator(); KeyInfoRetrievalMethod kiRetrievalMethod; KeyInfoName kiName; KeyInfoEncryptedKey kiEncKey; EncryptedKey ek = null; while (keyInfoEnum.MoveNext()) { kiName = keyInfoEnum.Current as KeyInfoName; if (kiName != null) { // Get the decryption key from the key mapping string keyName = kiName.Value; if ((SymmetricAlgorithm)_keyNameMapping[keyName] != null) { return((SymmetricAlgorithm)_keyNameMapping[keyName]); } // try to get it from a CarriedKeyName XmlNamespaceManager nsm = new XmlNamespaceManager(_document.NameTable); nsm.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl); XmlNodeList encryptedKeyList = _document.SelectNodes("//enc:EncryptedKey", nsm); if (encryptedKeyList != null) { foreach (XmlNode encryptedKeyNode in encryptedKeyList) { XmlElement encryptedKeyElement = encryptedKeyNode as XmlElement; EncryptedKey ek1 = new EncryptedKey(); ek1.LoadXml(encryptedKeyElement); if (ek1.CarriedKeyName == keyName && ek1.Recipient == Recipient) { ek = ek1; break; } } } break; } kiRetrievalMethod = keyInfoEnum.Current as KeyInfoRetrievalMethod; if (kiRetrievalMethod != null) { string idref = Utils.ExtractIdFromLocalUri(kiRetrievalMethod.Uri); ek = new EncryptedKey(); ek.LoadXml(GetIdElement(_document, idref)); break; } kiEncKey = keyInfoEnum.Current as KeyInfoEncryptedKey; if (kiEncKey != null) { ek = kiEncKey.EncryptedKey; break; } } // if we have an EncryptedKey, decrypt to get the symmetric key if (ek != null) { // now process the EncryptedKey, loop recursively // If the Uri is not provided by the application, try to get it from the EncryptionMethod if (symmetricAlgorithmUri == null) { if (encryptedData.EncryptionMethod == null) { throw new CryptographicException(SR.Cryptography_Xml_MissingAlgorithm); } symmetricAlgorithmUri = encryptedData.EncryptionMethod.KeyAlgorithm; } byte[] key = DecryptEncryptedKey(ek); if (key == null) { throw new CryptographicException(SR.Cryptography_Xml_MissingDecryptionKey); } SymmetricAlgorithm symAlg = (SymmetricAlgorithm)CryptoHelpers.CreateFromName(symmetricAlgorithmUri); symAlg.Key = key; return(symAlg); } return(null); }