Example #1
0
        // 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 (m_keyNameMapping != null)
            {
                encryptionKey = m_keyNameMapping[keyName];
            }

            if (encryptionKey == null)
            {
                throw new CryptographicException(SecurityResources.GetResourceString("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(SecurityResources.GetResourceString("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);
        }
Example #2
0
        // 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)m_keyNameMapping[keyName] != null)
                    {
                        return((SymmetricAlgorithm)m_keyNameMapping[keyName]);
                    }
                    // try to get it from a CarriedKeyName
                    XmlNamespaceManager nsm = new XmlNamespaceManager(m_document.NameTable);
                    nsm.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl);
                    XmlNodeList encryptedKeyList = m_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 == this.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(m_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(SecurityResources.GetResourceString("Cryptography_Xml_MissingAlgorithm"));
                    }
                    symmetricAlgorithmUri = encryptedData.EncryptionMethod.KeyAlgorithm;
                }
                byte[] key = DecryptEncryptedKey(ek);
                if (key == null)
                {
                    throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_MissingDecryptionKey"));
                }

                SymmetricAlgorithm symAlg = (SymmetricAlgorithm)GostCryptoConfig.CreateFromName(symmetricAlgorithmUri);
                symAlg.Key = key;
                return(symAlg);
            }
            return(null);
        }
Example #3
0
        // 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);
        }
Example #4
0
 public override void LoadXml(XmlElement value)
 {
     m_encryptedKey = new EncryptedKey();
     m_encryptedKey.LoadXml(value);
 }
Example #5
0
 public KeyInfoEncryptedKey(EncryptedKey encryptedKey)
 {
     m_encryptedKey = encryptedKey;
 }
        private SymmetricAlgorithm DecryptEncryptedKeyClass(EncryptedKey encryptedKey, string symmetricAlgorithmUri)
        {
            if (encryptedKey == null)
            {
                throw ExceptionUtility.ArgumentNull("encryptedKey");
            }

            SymmetricAlgorithm decryptionKey = null;

            if (encryptedKey.KeyInfo != null)
            {
                foreach (var keyInfo in encryptedKey.KeyInfo)
                {
                    // Извлечение ключа по имени
                    if (keyInfo is KeyInfoName)
                    {
                        var keyName      = ((KeyInfoName)keyInfo).Value;
                        var keyAlgorithm = KeyNameMapping[keyName];

                        if (keyAlgorithm != null)
                        {
                            if (keyAlgorithm is SymmetricAlgorithm)
                            {
                                decryptionKey = DecryptKeyClass(encryptedKey.CipherData.CipherValue, (SymmetricAlgorithm)keyAlgorithm, symmetricAlgorithmUri, encryptedKey.EncryptionMethod.KeyAlgorithm);
                            }
                            else if (keyAlgorithm is RSA)
                            {
                                var useOaep = (encryptedKey.EncryptionMethod != null) && (encryptedKey.EncryptionMethod.KeyAlgorithm == XmlEncRSAOAEPUrl);
                                decryptionKey = DecryptKeyClass(encryptedKey.CipherData.CipherValue, (RSA)keyAlgorithm, useOaep, symmetricAlgorithmUri);
                            }
                            else if (keyAlgorithm is Gost3410AsymmetricAlgorithmBase)
                            {
                                decryptionKey = DecryptKeyClass(encryptedKey.CipherData.CipherValue, (Gost3410AsymmetricAlgorithmBase)keyAlgorithm);
                            }
                        }

                        break;
                    }

                    // Извлечение ключа из сертификата
                    if (keyInfo is KeyInfoX509Data)
                    {
                        var certificates = GostXmlUtils.BuildBagOfCertsDecryption((KeyInfoX509Data)keyInfo);

                        foreach (var certificate in certificates)
                        {
                            var privateKey = certificate.GetPrivateKeyAlgorithm();

                            if (privateKey is RSA)
                            {
                                var useOaep = (encryptedKey.EncryptionMethod != null) && (encryptedKey.EncryptionMethod.KeyAlgorithm == XmlEncRSAOAEPUrl);
                                decryptionKey = DecryptKeyClass(encryptedKey.CipherData.CipherValue, (RSA)privateKey, useOaep, symmetricAlgorithmUri);
                            }
                            else if (privateKey is Gost3410AsymmetricAlgorithmBase)
                            {
                                decryptionKey = DecryptKeyClass(encryptedKey.CipherData.CipherValue, (Gost3410AsymmetricAlgorithmBase)privateKey);
                            }
                        }

                        break;
                    }

                    // Извлечение ключа по ссылке
                    if (keyInfo is KeyInfoRetrievalMethod)
                    {
                        var idValue   = GostXmlUtils.ExtractIdFromLocalUri(((KeyInfoRetrievalMethod)keyInfo).Uri);
                        var idElement = GetIdElement(Document, idValue);

                        if (idElement != null)
                        {
                            var secondEncryptedKey = new EncryptedKey();
                            secondEncryptedKey.LoadXml(idElement);

                            decryptionKey = DecryptEncryptedKeyClass(secondEncryptedKey, symmetricAlgorithmUri);
                        }

                        break;
                    }

                    // Ключ в готовом виде
                    if (keyInfo is KeyInfoEncryptedKey)
                    {
                        var secondEncryptedKey = ((KeyInfoEncryptedKey)keyInfo).EncryptedKey;
                        var symmetricAlgorithm = DecryptEncryptedKeyClass(secondEncryptedKey, symmetricAlgorithmUri);

                        if (symmetricAlgorithm != null)
                        {
                            decryptionKey = DecryptKeyClass(encryptedKey.CipherData.CipherValue, symmetricAlgorithm, symmetricAlgorithmUri, encryptedKey.EncryptionMethod.KeyAlgorithm);
                        }

                        break;
                    }
                }
            }

            return(decryptionKey);
        }
        public override SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri)
        {
            if (encryptedData == null)
            {
                throw ExceptionUtility.ArgumentNull("encryptedData");
            }

            SymmetricAlgorithm decryptionKey = null;

            if (encryptedData.KeyInfo != null)
            {
                EncryptedKey encryptedKey = null;

                foreach (var keyInfo in encryptedData.KeyInfo)
                {
                    // Извлечение ключа по имени
                    if (keyInfo is KeyInfoName)
                    {
                        var keyName      = ((KeyInfoName)keyInfo).Value;
                        var keyAlgorithm = KeyNameMapping[keyName];

                        if (keyAlgorithm == null)
                        {
                            var nsManager = new XmlNamespaceManager(Document.NameTable);
                            nsManager.AddNamespace("enc", XmlEncNamespaceUrl);

                            var encryptedKeyNodes = Document.SelectNodes("//enc:EncryptedKey", nsManager);

                            if (encryptedKeyNodes != null)
                            {
                                foreach (XmlElement encryptedKeyNode in encryptedKeyNodes)
                                {
                                    var currentEncryptedKey = new EncryptedKey();
                                    currentEncryptedKey.LoadXml(encryptedKeyNode);

                                    if ((currentEncryptedKey.CarriedKeyName == keyName) && (currentEncryptedKey.Recipient == Recipient))
                                    {
                                        encryptedKey = currentEncryptedKey;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            decryptionKey = (SymmetricAlgorithm)keyAlgorithm;
                        }

                        break;
                    }

                    // Извлечение ключа по ссылке
                    if (keyInfo is KeyInfoRetrievalMethod)
                    {
                        var idValue   = GostXmlUtils.ExtractIdFromLocalUri(((KeyInfoRetrievalMethod)keyInfo).Uri);
                        var idElement = GetIdElement(Document, idValue);

                        if (idElement != null)
                        {
                            encryptedKey = new EncryptedKey();
                            encryptedKey.LoadXml(idElement);
                        }

                        break;
                    }

                    // Ключ в готовом виде
                    if (keyInfo is KeyInfoEncryptedKey)
                    {
                        encryptedKey = ((KeyInfoEncryptedKey)keyInfo).EncryptedKey;
                        break;
                    }
                }

                if (decryptionKey == null && encryptedKey != null)
                {
                    if (symmetricAlgorithmUri == null)
                    {
                        if (encryptedData.EncryptionMethod == null)
                        {
                            throw ExceptionUtility.CryptographicException(Resources.XmlMissingAlgorithm);
                        }

                        symmetricAlgorithmUri = encryptedData.EncryptionMethod.KeyAlgorithm;
                    }

                    decryptionKey = DecryptEncryptedKeyClass(encryptedKey, symmetricAlgorithmUri);
                }
            }

            return(decryptionKey);
        }
Example #8
0
 /// <summary>
 /// Извлекает ключ из элемента &lt;EncryptedKey&gt;.
 /// </summary>
 /// <param name="encryptedKey">Элемент &lt;EncryptedKey&gt; с информацией о ключе шифрования.</param>
 /// <returns>Массив байт, содержащий ключ для расшифровки.</returns>
 public byte[] DecryptEncryptedKey(EncryptedKey encryptedKey)
 {
     return(_encryptedXml.DecryptEncryptedKey(encryptedKey));
 }