public override XmlNode Encrypt(XmlNode node)
        {
            RSACryptoServiceProvider cryptoServiceProvider = this.GetCryptoServiceProvider(false, false);
            XmlDocument document = new XmlDocument {
                PreserveWhitespace = true
            };

            document.LoadXml("<foo>" + node.OuterXml + "</foo>");
            EncryptedXml       xml                = new EncryptedXml(document);
            XmlElement         documentElement    = document.DocumentElement;
            SymmetricAlgorithm symmetricAlgorithm = new TripleDESCryptoServiceProvider();

            byte[] randomKey = this.GetRandomKey();
            symmetricAlgorithm.Key     = randomKey;
            symmetricAlgorithm.Mode    = CipherMode.ECB;
            symmetricAlgorithm.Padding = PaddingMode.PKCS7;
            byte[]        buffer        = xml.EncryptData(documentElement, symmetricAlgorithm, true);
            EncryptedData encryptedData = new EncryptedData {
                Type             = "http://www.w3.org/2001/04/xmlenc#Element",
                EncryptionMethod = new EncryptionMethod("http://www.w3.org/2001/04/xmlenc#tripledes-cbc"),
                KeyInfo          = new KeyInfo()
            };
            EncryptedKey encryptedKey = new EncryptedKey {
                EncryptionMethod = new EncryptionMethod("http://www.w3.org/2001/04/xmlenc#rsa-1_5"),
                KeyInfo          = new KeyInfo(),
                CipherData       = new CipherData()
            };

            encryptedKey.CipherData.CipherValue = EncryptedXml.EncryptKey(symmetricAlgorithm.Key, cryptoServiceProvider, this.UseOAEP);
            KeyInfoName clause = new KeyInfoName {
                Value = this._KeyName
            };

            encryptedKey.KeyInfo.AddClause(clause);
            KeyInfoEncryptedKey key2 = new KeyInfoEncryptedKey(encryptedKey);

            encryptedData.KeyInfo.AddClause(key2);
            encryptedData.CipherData             = new CipherData();
            encryptedData.CipherData.CipherValue = buffer;
            EncryptedXml.ReplaceElement(documentElement, encryptedData, true);
            foreach (XmlNode node2 in document.ChildNodes)
            {
                if (node2.NodeType == XmlNodeType.Element)
                {
                    foreach (XmlNode node3 in node2.ChildNodes)
                    {
                        if (node3.NodeType == XmlNodeType.Element)
                        {
                            return(node3);
                        }
                    }
                }
            }
            return(null);
        }
Exemplo n.º 2
0
        private void CheckEncryptionMethod(object algorithm, string uri)
        {
            XmlDocument doc = new XmlDocument();

            doc.LoadXml("<root />");
            EncryptedXml exml = new EncryptedXml();

            exml.AddKeyNameMapping("key", algorithm);

            EncryptedData edata       = exml.Encrypt(doc.DocumentElement, "key");
            IEnumerator   keyInfoEnum = edata.KeyInfo.GetEnumerator();

            keyInfoEnum.MoveNext();
            KeyInfoEncryptedKey kiEncKey = keyInfoEnum.Current as KeyInfoEncryptedKey;

            Assert.NotNull(edata);
            Assert.Equal(uri, kiEncKey.EncryptedKey.EncryptionMethod.KeyAlgorithm);
            Assert.NotNull(edata.CipherData.CipherValue);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Получает ключ для расшифровки на основе зашифрованных данных (из примеров криптопро)
        /// </summary>
        /// <param name="exml"></param>
        /// <param name="encryptedData"></param>
        /// <returns>Алгоритм для расшифровки</returns>
        private SymmetricAlgorithm GetDecryptionKey(EncryptedXml exml, EncryptedData encryptedData)
        {
            IEnumerator encryptedKeyEnumerator = encryptedData.KeyInfo.GetEnumerator();

            // Проходим по всем KeyInfo
            while (encryptedKeyEnumerator.MoveNext())
            {
                // Пропускам все что неизвестно.
                KeyInfoEncryptedKey current = encryptedKeyEnumerator.Current as KeyInfoEncryptedKey;
                if (current == null)
                {
                    continue;
                }
                // До первого EncryptedKey
                EncryptedKey encryptedKey = current.EncryptedKey;
                if (encryptedKey == null)
                {
                    continue;
                }
                KeyInfo keyinfo = encryptedKey.KeyInfo;
                // Проходим по всем KeyInfo зашифрования ключа.
                IEnumerator srcKeyEnumerator = keyinfo.GetEnumerator();
                while (srcKeyEnumerator.MoveNext())
                {
                    // Пропускам все что неизвестно.
                    KeyInfoX509Data keyInfoCert = srcKeyEnumerator.Current
                                                  as KeyInfoX509Data;
                    if (keyInfoCert == null)
                    {
                        continue;
                    }
                    AsymmetricAlgorithm alg   = certOur.PrivateKey; // Приватный ключ, открытый ключ которого мы отправляли при шифровании запроса
                    Gost3410            myKey = alg as Gost3410;    // Преобразования
                    if (myKey == null)
                    {
                        continue;
                    }
                    // Получаем и возвращаем ключ для расшифровки
                    return(CPEncryptedXml.DecryptKeyClass(encryptedKey.CipherData.CipherValue, myKey, encryptedData.EncryptionMethod.KeyAlgorithm));
                }
            }
            return(null);
        }
Exemplo n.º 4
0
        // Override EncryptedXml.GetDecryptionKey to avoid calling into CryptoConfig.CreateFromName
        // When detect AES, we need to return AesCryptoServiceProvider (FIPS certified) instead of AesManaged (FIPS obsolated)
        public override SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri)
        {
            // If AES is used then assume FIPS is required
            bool fipsRequired = IsAesDetected(encryptedData, symmetricAlgorithmUri);

            if (fipsRequired)
            {
                // Obtain the EncryptedKey
                EncryptedKey ek = null;

                foreach (var ki in encryptedData.KeyInfo)
                {
                    KeyInfoEncryptedKey kiEncKey = ki as KeyInfoEncryptedKey;
                    if (kiEncKey != null)
                    {
                        ek = kiEncKey.EncryptedKey;
                        break;
                    }
                }

                // Got an EncryptedKey, decrypt it to get the AES key
                if (ek != null)
                {
                    byte[] key = DecryptEncryptedKey(ek);

                    // Construct FIPS-certified AES provider
                    if (key != null)
                    {
                        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
                        aes.Key = key;

                        return(aes);
                    }
                }
            }

            // Fallback to the base implementation
            return(base.GetDecryptionKey(encryptedData, symmetricAlgorithmUri));
        }
Exemplo n.º 5
0
        public Stream Decrypt(EncryptionMethod encryptionMethod, KeyInfo keyInfo, Stream toDecrypt)
        {
            Assert.NotNull(encryptionMethod);
            Assert.NotNull(keyInfo);
            Assert.NotNull(toDecrypt);
            Assert.True(encryptionMethod.KeyAlgorithm == EncryptedXml.XmlEncAES128Url ||
                        encryptionMethod.KeyAlgorithm == EncryptedXml.XmlEncAES192Url ||
                        encryptionMethod.KeyAlgorithm == EncryptedXml.XmlEncAES256Url);

            Assert.Equal(keyInfo.Count, 1);

            byte[] decryptedKey = null;

            foreach (KeyInfoClause clause in keyInfo)
            {
                if (clause is KeyInfoEncryptedKey)
                {
                    KeyInfoEncryptedKey encryptedKeyInfo = clause as KeyInfoEncryptedKey;
                    EncryptedKey        encryptedKey     = encryptedKeyInfo.EncryptedKey;

                    Assert.Equal(encryptedKey.EncryptionMethod.KeyAlgorithm, EncryptedXml.XmlEncRSAOAEPUrl);
                    Assert.Equal(encryptedKey.KeyInfo.Count, 1);
                    Assert.NotEqual(_asymmetricKeys.Count, 0);

                    RSAParameters rsaParams      = new RSAParameters();
                    RSAParameters rsaInputParams = new RSAParameters();

                    foreach (KeyInfoClause rsa in encryptedKey.KeyInfo)
                    {
                        if (rsa is RSAKeyValue)
                        {
                            rsaParams = (rsa as RSAKeyValue).Key.ExportParameters(false);
                            break;
                        }
                        else
                        {
                            Assert.True(false, "Invalid License - MalformedKeyInfoClause");
                        }
                    }

                    bool keyMismatch = true;
                    foreach (AsymmetricAlgorithm key in _asymmetricKeys)
                    {
                        RSA rsaKey = key as RSA;
                        Assert.NotNull(rsaKey);

                        rsaInputParams = rsaKey.ExportParameters(false);

                        if (!PublicKeysEqual(rsaParams, rsaInputParams))
                        {
                            continue;
                        }

                        keyMismatch = false;

                        // Decrypt session key
                        byte[] encryptedKeyValue = encryptedKey.CipherData.CipherValue;

                        if (encryptedKeyValue == null)
                        {
                            throw new CryptographicException("MissingKeyCipher");
                        }

                        decryptedKey = EncryptedXml.DecryptKey(encryptedKeyValue,
                                                               rsaKey, true);
                        break;
                    }

                    if (keyMismatch)
                    {
                        throw new Exception("Invalid License - AsymmetricKeyMismatch");
                    }
                }
                else if (clause is KeyInfoName)
                {
                    Assert.True(false, "This test should not have KeyInfoName clauses");
                }
                else
                {
                    throw new CryptographicException("MalformedKeyInfoClause");
                }

                break;
            }

            if (decryptedKey == null)
            {
                throw new CryptographicException("KeyDecryptionFailure");
            }

            using (Aes aes = Aes.Create())
            {
                aes.Key     = decryptedKey;
                aes.Padding = PaddingMode.PKCS7;
                aes.Mode    = CipherMode.CBC;
                return(DecryptStream(toDecrypt, aes));
            }
        }
        /// <summary>
        /// Encrypts the XML node passed to it.
        /// </summary>
        /// <param name="node">The XmlNode to encrypt.</param>
        /// <returns></returns>
        public override XmlNode Encrypt(XmlNode node)
        {
            // Get the RSA public key to encrypt the node. This key will encrypt
            // a symmetric key, which will then be encryped in the XML document.
            RSACryptoServiceProvider cryptoServiceProvider = this.GetCryptoServiceProvider(true);

            // Create an XML document and load the node to be encrypted in it.
            XmlDocument document = new XmlDocument();

            document.PreserveWhitespace = true;
            document.LoadXml("<Data>" + node.OuterXml + "</Data>");

            // Create a new instance of the EncryptedXml class
            // and use it to encrypt the XmlElement with the
            // a new random symmetric key.
            EncryptedXml       xml                = new EncryptedXml(document);
            XmlElement         documentElement    = document.DocumentElement;
            SymmetricAlgorithm symmetricAlgorithm = new RijndaelManaged();

            // Create a 192 bit random key.
            symmetricAlgorithm.Key = this.GetRandomKey();
            symmetricAlgorithm.GenerateIV();
            symmetricAlgorithm.Padding = PaddingMode.PKCS7;

            byte[] buffer = xml.EncryptData(documentElement, symmetricAlgorithm, true);

            // Construct an EncryptedData object and populate
            // it with the encryption information.
            EncryptedData encryptedData = new EncryptedData();

            encryptedData.Type = EncryptedXml.XmlEncElementUrl;

            // Create an EncryptionMethod element so that the
            // receiver knows which algorithm to use for decryption.
            encryptedData.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES192Url);
            encryptedData.KeyInfo          = new KeyInfo();

            // Encrypt the session key and add it to an EncryptedKey element.
            EncryptedKey encryptedKey = new EncryptedKey();

            encryptedKey.EncryptionMethod       = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);
            encryptedKey.KeyInfo                = new KeyInfo();
            encryptedKey.CipherData             = new CipherData();
            encryptedKey.CipherData.CipherValue = EncryptedXml.EncryptKey(symmetricAlgorithm.Key, cryptoServiceProvider, false);
            KeyInfoName clause = new KeyInfoName();

            clause.Value = "rsaKey";

            // Add the encrypted key to the EncryptedData object.
            encryptedKey.KeyInfo.AddClause(clause);
            KeyInfoEncryptedKey key2 = new KeyInfoEncryptedKey(encryptedKey);

            encryptedData.KeyInfo.AddClause(key2);
            encryptedData.CipherData             = new CipherData();
            encryptedData.CipherData.CipherValue = buffer;

            // Replace the element from the original XmlDocument
            // object with the EncryptedData element.
            EncryptedXml.ReplaceElement(documentElement, encryptedData, true);
            foreach (XmlNode node2 in document.ChildNodes)
            {
                if (node2.NodeType == XmlNodeType.Element)
                {
                    foreach (XmlNode node3 in node2.ChildNodes)
                    {
                        if (node3.NodeType == XmlNodeType.Element)
                        {
                            return(node3);
                        }
                    }
                }
            }
            return(null);
        }
        public Stream Decrypt(EncryptionMethod encryptionMethod, KeyInfo keyInfo, Stream toDecrypt)
        {
            Assert.NotNull(encryptionMethod);
            Assert.NotNull(keyInfo);
            Assert.NotNull(toDecrypt);
            Assert.True(encryptionMethod.KeyAlgorithm == NS.XmlEncAES128Url ||
                        encryptionMethod.KeyAlgorithm == NS.XmlEncAES192Url ||
                        encryptionMethod.KeyAlgorithm == NS.XmlEncAES256Url);

            Assert.Equal(keyInfo.Count, 1);

            byte[] decryptedKey = null;

            foreach (KeyInfoClause clause in keyInfo)
            {
                if (clause is KeyInfoEncryptedKey)
                {
                    KeyInfoEncryptedKey encryptedKeyInfo = clause as KeyInfoEncryptedKey;
                    EncryptedKey        encryptedKey     = encryptedKeyInfo.GetEncryptedKey();

                    Assert.Equal(encryptedKey.EncryptionMethod.KeyAlgorithm, NS.XmlEncRSAOAEPUrl);
                    Assert.Equal(encryptedKey.KeyInfo.Count, 1);
                    Assert.NotEqual(_asymmetricKeys.Count, 0);

                    RsaKeyParameters rsaParams      = null;
                    RsaKeyParameters rsaInputParams = null;

                    foreach (KeyInfoClause rsa in encryptedKey.KeyInfo)
                    {
                        if (rsa is RsaKeyValue)
                        {
                            rsaParams = (rsa as RsaKeyValue).GetKey();
                            break;
                        }
                        else
                        {
                            Assert.True(false, "Invalid License - MalformedKeyInfoClause");
                        }
                    }

                    bool keyMismatch = true;
                    foreach (AsymmetricCipherKeyPair key in _asymmetricKeys)
                    {
                        RsaKeyParameters rsaKey = key.Private as RsaKeyParameters;
                        Assert.NotNull(rsaKey);

                        rsaInputParams = key.Public as RsaKeyParameters;
                        Assert.NotNull(rsaInputParams);

                        if (!PublicKeysEqual(rsaParams, rsaInputParams))
                        {
                            continue;
                        }

                        keyMismatch = false;


                        byte[] encryptedKeyValue = encryptedKey.CipherData.CipherValue;

                        if (encryptedKeyValue == null)
                        {
                            throw new System.Security.Cryptography.CryptographicException("MissingKeyCipher");
                        }

                        decryptedKey = XmlDecryption.DecryptKey(encryptedKeyValue,
                                                                rsaKey, true);
                        break;
                    }

                    if (keyMismatch)
                    {
                        throw new Exception("Invalid License - AsymmetricKeyMismatch");
                    }
                }
                else if (clause is KeyInfoName)
                {
                    Assert.True(false, "This test should not have KeyInfoName clauses");
                }
                else
                {
                    throw new System.Security.Cryptography.CryptographicException("MalformedKeyInfoClause");
                }

                break;
            }

            if (decryptedKey == null)
            {
                throw new System.Security.Cryptography.CryptographicException("KeyDecryptionFailure");
            }

            return(DecryptStream(toDecrypt, new KeyParameter(decryptedKey), "AES/CBC/PKCS7"));
        }
Exemplo n.º 8
0
        public override XmlNode Encrypt(XmlNode node)
        {
            XmlDocument  xmlDocument;
            EncryptedXml exml;

            byte[]                   rgbOutput;
            EncryptedData            ed;
            KeyInfoName              kin;
            EncryptedKey             ek;
            KeyInfoEncryptedKey      kek;
            XmlElement               inputElement;
            RSACryptoServiceProvider rsa = GetCryptoServiceProvider(false, false);

            // Encrypt the node with the new key
            xmlDocument = new XmlDocument();
            xmlDocument.PreserveWhitespace = true;
            xmlDocument.LoadXml("<foo>" + node.OuterXml + "</foo>");
            exml         = new EncryptedXml(xmlDocument);
            inputElement = xmlDocument.DocumentElement;

            using (SymmetricAlgorithm symAlg = GetSymAlgorithmProvider()) {
                rgbOutput           = exml.EncryptData(inputElement, symAlg, true);
                ed                  = new EncryptedData();
                ed.Type             = EncryptedXml.XmlEncElementUrl;
                ed.EncryptionMethod = GetSymEncryptionMethod();
                ed.KeyInfo          = new KeyInfo();

                ek = new EncryptedKey();
                ek.EncryptionMethod       = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);
                ek.KeyInfo                = new KeyInfo();
                ek.CipherData             = new CipherData();
                ek.CipherData.CipherValue = EncryptedXml.EncryptKey(symAlg.Key, rsa, UseOAEP);
            }

            kin       = new KeyInfoName();
            kin.Value = _KeyName;
            ek.KeyInfo.AddClause(kin);
            kek = new KeyInfoEncryptedKey(ek);
            ed.KeyInfo.AddClause(kek);
            ed.CipherData             = new CipherData();
            ed.CipherData.CipherValue = rgbOutput;
            EncryptedXml.ReplaceElement(inputElement, ed, true);

            rsa.Clear();

            // Get node from the document
            foreach (XmlNode node2 in xmlDocument.ChildNodes)
            {
                if (node2.NodeType == XmlNodeType.Element)
                {
                    foreach (XmlNode node3 in node2.ChildNodes) // node2 is the "foo" node
                    {
                        if (node3.NodeType == XmlNodeType.Element)
                        {
                            return(node3); // node3 is the "EncryptedData" node
                        }
                    }
                }
            }
            return(null);
        }
Exemplo n.º 9
0
        /// <summary>
        /// An example on how to decrypt an encrypted assertion.
        /// </summary>
        private static void DecryptAssertion(string file)
        {
            XmlDocument doc = new XmlDocument();

            doc.Load(file);
            XmlElement encryptedDataElement = GetElement(dk.nita.saml20.Schema.XEnc.EncryptedData.ELEMENT_NAME, Saml20Constants.XENC, doc);


            EncryptedData encryptedData = new EncryptedData();

            encryptedData.LoadXml(encryptedDataElement);

            XmlNodeList nodelist = doc.GetElementsByTagName(dk.nita.saml20.Schema.XmlDSig.KeyInfo.ELEMENT_NAME, Saml20Constants.XMLDSIG);

            Assert.That(nodelist.Count > 0);

            KeyInfo key = new KeyInfo();

            key.LoadXml((XmlElement)nodelist[0]);

            // Review: Is it possible to figure out which certificate to load based on the Token?

            /*
             * Comment:
             * It would be possible to provide a key/certificate identifier in the EncryptedKey element, which contains the "recipient" attribute.
             * The implementation (Safewhere.Tokens.Saml20.Saml20EncryptedAssertion) currently just expects an appropriate asymmetric key to be provided,
             * and is not not concerned about its origin.
             * If the need arises, we can easily extend the Saml20EncryptedAssertion class with a property that allows extraction key info, eg. the "recipient"
             * attribute.
             */
            X509Certificate2 cert = new X509Certificate2(@"Saml20\Certificates\sts_dev_certificate.pfx", "test1234");

            // ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.NETDEVFX.v20.en/CPref18/html/T_System_Security_Cryptography_Xml_KeyInfoClause_DerivedTypes.htm
            // Look through the list of KeyInfo elements to find the encrypted key.
            SymmetricAlgorithm symmetricKey = null;

            foreach (KeyInfoClause keyInfoClause in key)
            {
                if (keyInfoClause is KeyInfoEncryptedKey)
                {
                    KeyInfoEncryptedKey keyInfoEncryptedKey = (KeyInfoEncryptedKey)keyInfoClause;
                    EncryptedKey        encryptedKey        = keyInfoEncryptedKey.EncryptedKey;
                    symmetricKey = new RijndaelManaged();

                    symmetricKey.Key =
                        EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, (RSA)cert.PrivateKey, false);
                    continue;
                }
            }
            // Explode if we didn't manage to find a viable key.
            Assert.IsNotNull(symmetricKey);
            EncryptedXml encryptedXml = new EncryptedXml();

            byte[] plaintext = encryptedXml.DecryptData(encryptedData, symmetricKey);

            XmlDocument assertion = new XmlDocument();

            assertion.Load(new StringReader(System.Text.Encoding.UTF8.GetString(plaintext)));

            // A very simple test to ensure that there is indeed an assertion in the plaintext.
            Assert.AreEqual(Assertion.ELEMENT_NAME, assertion.DocumentElement.LocalName);
            Assert.AreEqual(Saml20Constants.ASSERTION, assertion.DocumentElement.NamespaceURI);
        }