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);
        }
Esempio n. 2
0
        protected override AsymmetricAlgorithm GetPublicKey()
        {
            if (KeyInfo == null)
            {
                throw ExceptionUtility.CryptographicException(Resources.XmlKeyInfoRequired);
            }

            if (X509Enumumerable != null)
            {
                var nextCertificatePublicKey = GetNextCertificatePublicKey();

                if (nextCertificatePublicKey != null)
                {
                    return(nextCertificatePublicKey);
                }
            }

            if (KeyInfoEnumerable == null)
            {
                KeyInfoEnumerable = KeyInfo.GetEnumerator();
            }

            var keyInfoEnum = KeyInfoEnumerable;

            while (keyInfoEnum.MoveNext())
            {
                var rsaKeyValue = keyInfoEnum.Current as RSAKeyValue;

                if (rsaKeyValue != null)
                {
                    return(rsaKeyValue.Key);
                }

                var dsaKeyValue = keyInfoEnum.Current as DSAKeyValue;

                if (dsaKeyValue != null)
                {
                    return(dsaKeyValue.Key);
                }

                var gostKeyValue = keyInfoEnum.Current as GostKeyValue;

                if (gostKeyValue != null)
                {
                    return(gostKeyValue.Key);
                }

                var keyInfoX509Data = keyInfoEnum.Current as KeyInfoX509Data;

                if (keyInfoX509Data != null)
                {
                    X509Collection = GostXmlUtils.BuildBagOfCertsVerification(keyInfoX509Data);

                    if (X509Collection.Count > 0)
                    {
                        X509Enumumerable = X509Collection.GetEnumerator();

                        var nextCertificatePublicKey = GetNextCertificatePublicKey();

                        if (nextCertificatePublicKey != null)
                        {
                            return(nextCertificatePublicKey);
                        }
                    }
                }
            }

            return(null);
        }
        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);
        }