КриптоПро .NET
Search Results for

    Показать/Скрыть содержание

    XML шифрование на асимметричном ключе.

    /// <summary>
    /// Вспомогательный прокси метод для тестирования шифрования на асимметричном ключе
    /// </summary>
    /// <param name="gostKey"></param>
    private void Encrypt(AsymmetricAlgorithm gostKey)
    {
        if (gostKey is Gost3410 gost3410)
        {
            Console.WriteLine("Секретный ключ получен.");
            // и получаем открытый ключ.
            Gost3410Parameters publicKey = gost3410.ExportParameters();
    
            Console.WriteLine("На стороне отправителя...");
            // Полученный открытый ключ передаем отправителю сообщения.
            using (Gost3410CryptoServiceProvider pubKey = new Gost3410CryptoServiceProvider())
            {
    
                pubKey.ImportParameters(publicKey);
                Console.WriteLine("Открытый ключ получен.");
    
                // Создаем Xml файл для зашифрования.
                CreateSomeXml("ato_encrypt_2001.xml");
                Console.WriteLine("Создан новый XML файл.");
    
                // Зашифровываем узел, заданный xpath выражением, XML документа 
                // ato_encrypt.xml в документ a_encrypted.xml
                // Для зашифрования используется открытый ключ pubKey.
                Encrypt("ato_encrypt_2001.xml", "a_encrypted_2001.xml",
                    "//SomeNode[@ToEncrypt='true']",
                    "EncryptedElement1", pubKey, "KeyAlias");
                Console.WriteLine("Узел XML файла зашифрован.");
    
                Console.WriteLine("На стороне получателя...");
    
                Decrypt("a_encrypted_2001.xml", "a_decrypted_2001.xml", gost3410, "KeyAlias");
            }
        }
        else if (gostKey is Gost3410_2012_256 gost3410_2012_256)
        {
            Console.WriteLine("Секретный ключ получен.");
            // и получаем открытый ключ.
            Gost3410Parameters publicKey = gost3410_2012_256.ExportParameters();
    
            Console.WriteLine("На стороне отправителя...");
            // Полученный открытый ключ передаем отправителю сообщения.
            using (Gost3410_2012_256CryptoServiceProvider pubKey = new Gost3410_2012_256CryptoServiceProvider())
            {
                pubKey.ImportParameters(publicKey);
                Console.WriteLine("Открытый ключ получен.");
    
                // Создаем Xml файл для зашифрования.
                CreateSomeXml("ato_encrypt_2012_256.xml");
                Console.WriteLine("Создан новый XML файл.");
    
                // Зашифровываем узел, заданный xpath выражением, XML документа 
                // ato_encrypt.xml в документ a_encrypted.xml
                // Для зашифрования используется открытый ключ pubKey.
                Encrypt("ato_encrypt_2012_256.xml", "a_encrypted_2012_256.xml",
                    "//SomeNode[@ToEncrypt='true']",
                    "EncryptedElement1", pubKey, "KeyAlias");
                Console.WriteLine("Узел XML файла зашифрован.");
    
                Console.WriteLine("На стороне получателя...");
    
                Decrypt("a_encrypted_2012_256.xml", "a_decrypted_2012_256.xml", gost3410_2012_256, "KeyAlias");
            }
        }
        else if (gostKey is Gost3410_2012_512 gost3410_2012_512)
        {
            Console.WriteLine("Секретный ключ получен.");
            // и получаем открытый ключ.
            Gost3410Parameters publicKey = gost3410_2012_512.ExportParameters();
    
            Console.WriteLine("На стороне отправителя...");
            // Полученный открытый ключ передаем отправителю сообщения.
            using (Gost3410_2012_512CryptoServiceProvider pubKey = new Gost3410_2012_512CryptoServiceProvider())
            {
                pubKey.ImportParameters(publicKey);
                Console.WriteLine("Открытый ключ получен.");
    
                // Создаем Xml файл для зашифрования.
                CreateSomeXml("ato_encrypt_2012_512.xml");
                Console.WriteLine("Создан новый XML файл.");
    
                // Зашифровываем узел, заданный xpath выражением, XML документа 
                // ato_encrypt.xml в документ a_encrypted.xml
                // Для зашифрования используется открытый ключ pubKey.
                Encrypt("ato_encrypt_2012_512.xml", "a_encrypted_2012_512.xml",
                    "//SomeNode[@ToEncrypt='true']",
                    "EncryptedElement1", pubKey, "KeyAlias");
                Console.WriteLine("Узел XML файла зашифрован.");
    
                Console.WriteLine("На стороне получателя...");
    
                Decrypt("a_encrypted_2012_512.xml", "a_decrypted_2012_512bui.xml", gost3410_2012_512, "KeyAlias");
            }
        }
        else
        {
            throw new NotSupportedException();
        }
    
        Console.WriteLine("XML документ расшифрован.");
    }
    

    Расшифрование XML на асимметричном ключе.

    // Расшифрование узла XML документа на асимметричном ключе
    private static void Decrypt(string srcName, string destName,
        AsymmetricAlgorithm alg, string KeyName)
    {
        // Создаем новый объект xml документа.
        XmlDocument xmlDoc = new XmlDocument();
    
        // Пробельные символы участвуют в вычислении подписи и должны быть сохранены для совместимости с другими реализациями
        xmlDoc.PreserveWhitespace = true;
    
        // Загружаем в объект созданный XML документ.
        xmlDoc.Load(srcName);
    
        // Создаем объект CpEncryptedXml.
        CpEncryptedXml exml = new CpEncryptedXml(xmlDoc);
    
        // Добавляем отображение имен в ключи.
        // Нижеследующий метод сможет расшифровать
        // только те документы, для которых будет 
        // найдены соответсвующие ключи.
    
        if (alg is Gost3410 gost3410)
        {
            exml.AddKeyNameMapping(KeyName, gost3410);
        }
        else if (alg is Gost3410_2012_256 gost3410_2012_256)
        {
            exml.AddKeyNameMapping(KeyName, gost3410_2012_256);
        }
        else if (alg is Gost3410_2012_512 gost3410_2012_512)
        {
            exml.AddKeyNameMapping(KeyName, gost3410_2012_512);
        }
        else
        {
            throw new NotSupportedException();
        }
    
        // Расшифровываем зашифрованные элементы.
        exml.DecryptDocument();
    
        // Сохраняем расшифрованный документ.
        xmlDoc.Save(destName);
    }
    

    XML шифрование на сертификате

    /// <summary>
    /// Вспомогательный прокси метод для тестирования шифрования на сертификате
    /// </summary>
    private void Encrypt(CpX509Certificate2 cert)
    {
        // Создаем тестовый XML документ.
        CreateSomeXml($"doc_to_encrypt_{cert.SubjectName}.xml");
    
        // Создаем объект XmlDocument.
        XmlDocument xmlDoc = new XmlDocument();
    
        // Загружаем XML файл в объект XmlDocument.
        xmlDoc.PreserveWhitespace = true;
        xmlDoc.Load($"doc_to_encrypt_{cert.SubjectName}.xml");
    
        // Шифруем узел SomeNode, который содержит атрибут ToEncrypt со значением true
        Encrypt(xmlDoc, "//SomeNode[@ToEncrypt='true']", cert);
    
        // Сохраняем XML документ.
        xmlDoc.Save($"d_encrypted_{cert.SubjectName}.xml");
    }
    
    

    Расшифрование XML на сертификате

    /// <summary>
    /// Расшифрование на сертификате
    /// </summary>
    /// <param name="gostKey"></param>
    static void Decrypt(string srcName, string destName, CpX509Certificate2 cert)
    {
        // Создаем новый объект xml документа.
        XmlDocument xmlDoc = new XmlDocument();
    
        // Пробельные символы участвуют в вычислении подписи и должны быть сохранены для совместимости с другими реализациями
        xmlDoc.PreserveWhitespace = true;
    
        // Загружаем в объект созданный XML документ.
        xmlDoc.Load(srcName);
    
        // Создаем новый объект CpEncryptedXml по XML документу.
        CpEncryptedXml exml = new CpEncryptedXml(xmlDoc);
    
        // Небольшие хаки, чтобы не устанавливать серт в хранилище
        {
            var ns = new XmlNamespaceManager(xmlDoc.NameTable);
            ns.AddNamespace("ki", "http://www.w3.org/2000/09/xmldsig#");
            ns.AddNamespace("ek", "http://www.w3.org/2001/04/xmlenc#");
            var keyName = Convert.ToBase64String(cert.Export(X509ContentType.Cert));
            var keyInfoNode = xmlDoc.SelectSingleNode("//ki:KeyInfo/ek:EncryptedKey/ki:KeyInfo", ns);
            if (keyInfoNode == null)
            {
                throw new InvalidOperationException("Неверный формат зашифрованного XML-документа.");
            }
    
            if (keyInfoNode.InnerText.Equals(keyName, StringComparison.InvariantCultureIgnoreCase))
            {
                keyInfoNode.InnerXml = $"<KeyName>{keyName}</KeyName>";
            }
            exml.AddKeyNameMapping(keyName, cert.PrivateKey);
            exml.Recipient = keyName;
        }
    
        // Расшифровываем зашифрованные узлы XML документа.
        exml.DecryptDocument();
    
        // Сохраняем расшифрованный документ.
        xmlDoc.Save(destName);
    }
    

    XML шифрование на симметричном ключе

    // Зашифрование узла XML документа на симметричном ключе
    private static void Encrypt(string srcName, string destName,
        string xpath, SymmetricAlgorithm Key)
    {
        // Создаем новый объект xml документа.
        XmlDocument xmlDoc = new XmlDocument();
    
        // Пробельные символы участвуют в вычислении подписи и должны быть сохранены для совместимости с другими реализациями.
        xmlDoc.PreserveWhitespace = true;
    
        // Загружаем в объект созданный XML документ.
        xmlDoc.Load(srcName);
    
        // Ищем заданный элемент для зашифрования.
        XmlElement elementToEncrypt = xmlDoc.SelectSingleNode(xpath)
            as XmlElement;
        if (elementToEncrypt == null)
            throw new XmlException("Узел не найден");
    
        // Создаем объект класса EncryptedXml и используем 
        // его для зашифрования узла на симметричном ключе.
        CpEncryptedXml eXml = new CpEncryptedXml();
    
        byte[] encryptedElement = eXml.EncryptData(
            elementToEncrypt, Key, false);
    
        // Создаем объект EncryptedData и заполняем его
        // необходимой информацией.
        CpEncryptedData edElement = new CpEncryptedData();
        edElement.Type = EncryptedXml.XmlEncElementUrl;
    
        // Заполняем алгоритм зашифрования данных. 
        // Он будет использован при расшифровании.
        edElement.EncryptionMethod = new CpEncryptionMethod(
            CpEncryptedXml.XmlEncGost28147Url);
    
        // Добавляем зашифрованные данные 
        // к объекту EncryptedData.
        edElement.CipherData.CipherValue = encryptedElement;
    
        // Заменяем исходный узел на зашифрованный.
        CpEncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
    
        // Сохраняем зашифрованный документ.
        xmlDoc.Save(destName);
    }
    

    Расшифрование XML на симметричном ключе.

    // Расшифрование узла XML документа на симметричном ключе
    private static void Decrypt(string srcName, string destName, SymmetricAlgorithm Alg)
    {
        // Создаем новый объект xml документа.
        XmlDocument xmlDoc = new XmlDocument();
    
        // Пробельные символы участвуют в вычислении подписи и должны быть сохранены для совместимости с другими реализациями.
        xmlDoc.PreserveWhitespace = true;
    
        // Загружаем в объект созданный XML документ.
        xmlDoc.Load(srcName);
    
        // Ищем узел для расшифрования.
        XmlElement encryptedElement = xmlDoc.GetElementsByTagName(
            "EncryptedData")[0] as XmlElement;
        if (encryptedElement == null)
            throw new XmlException("Узел EncryptedData не найден");
    
        // Создаем объект EncryptedData.
        CpEncryptedData edElement = new CpEncryptedData();
        // и загружаем в него зашифрованный узел
        edElement.LoadXml(encryptedElement);
    
        // Создаем объект CpEncryptedXml
        CpEncryptedXml exml = new CpEncryptedXml();
    
        // Расшифровываем элемент используя 
        // симметричный ключ.
        byte[] rgbOutput = exml.DecryptData(edElement, Alg);
    
        // Заменяем зашифрованный узел расшифрованным 
        exml.ReplaceData(encryptedElement, rgbOutput);
    
        // Сохраняем расшифрованный документ.
        xmlDoc.Save(destName);
    }
    

    Вспомогательные функции

    // Зашифрование узла XML документа на асимметричном ключе
    private static void Encrypt(string srcName, string destName,
        string xpath, string EncryptionElementID, AsymmetricAlgorithm alg,
        string KeyName)
    {
        // Создаем новый объект xml документа.
        XmlDocument xmlDoc = new XmlDocument();
    
        // Пробельные символы участвуют в вычислении подписи и должны быть сохранены для совместимости с другими реализациями
        xmlDoc.PreserveWhitespace = true;
    
        // Загружаем в объект созданный XML документ.
        xmlDoc.Load(srcName);
    
        // Ищем заданный элемент для зашифрования.
        XmlElement elementToEncrypt = xmlDoc.SelectSingleNode(xpath)
            as XmlElement;
        if (elementToEncrypt == null)
            throw new XmlException("Узел не найден");
    
        // Создаем случайный симметричный ключ.
        // В целях безопасности удаляем ключ из памяти после использования.
        using (Gost28147CryptoServiceProvider sessionKey =
            new Gost28147CryptoServiceProvider())
        {
            // Создаем объект класса CpEncryptedXml и используем 
            // его для зашифрования узла на случайной симметричном ключе.
            CpEncryptedXml eXml = new CpEncryptedXml();
    
            // Зашифровываем элемент на сессионном ключе.
            byte[] encryptedElement = eXml.EncryptData(elementToEncrypt,
                sessionKey, false);
    
            // Создаем объект EncryptedData и заполняем его
            // необходимой информацией.
            CpEncryptedData edElement = new CpEncryptedData();
            // Тип элемента зашифрованный узел
            edElement.Type = CpEncryptedXml.XmlEncElementUrl;
            // Созданный элемент помечаем EncryptionElementID
            edElement.Id = EncryptionElementID;
    
            // Заполняем алгоритм зашифрования данных. 
            // Он будет использован при расшифровании.
            edElement.EncryptionMethod = new CpEncryptionMethod(
                CpEncryptedXml.XmlEncGost28147Url);
    
            // Зашифровываем сессионный ключ и добавляем эти зашифрованные данные
            // к узлу EncryptedKey.
            CpEncryptedKey ek = new CpEncryptedKey();
            byte[] encryptedKey;
    
            if (alg is Gost3410 gost3410)
            {
                encryptedKey = CpEncryptedXml.EncryptKey(sessionKey, gost3410);
            }
            else if (alg is Gost3410_2012_256 gost3410_2012_256)
            {
                encryptedKey = CpEncryptedXml.EncryptKey(sessionKey, gost3410_2012_256);
            }
            else if (alg is Gost3410_2012_512 gost3410_2012_512)
            {
                encryptedKey = CpEncryptedXml.EncryptKey(sessionKey, gost3410_2012_512);
            }
            else
            {
                throw new NotSupportedException();
            }
            ek.CipherData = new CpCipherData(encryptedKey);
            ek.EncryptionMethod = new CpEncryptionMethod(
                CpEncryptedXml.XmlEncGostKeyTransportUrl);
    
            // Создаем элемент DataReference для KeyInfo.
            // Эта необязательная операция позволяет указать
            // какие данные используют данный ключ.
            // XML документ может содержать несколько
            // элементов EncryptedData с различными ключами.
            CpDataReference dRef = new CpDataReference();
    
            // Указываем URI EncryptedData.
            // Для этого используем ранее проставленную ссылку
            // EncryptionElementID
            dRef.Uri = "#" + EncryptionElementID;
    
            // Добавляем к EncryptedKey ссылку на зашифрованные 
            // данные.
            ek.AddReference(dRef);
    
            // Создаем новую ссылку на ключ.
            edElement.KeyInfo = new CpKeyInfo();
    
            // Добавляем ссылку на зашифрованный ключ к 
            // зашифрованным данным.
            edElement.KeyInfo.AddClause(new CpKeyInfoEncryptedKey(ek));
    
            // Указываем имя асимметричного ключа.
    
            // Создаем новый элемент KeyInfoName 
            CpKeyInfoName kin = new CpKeyInfoName();
    
            // Указываем имя асимметричного ключа.
            kin.Value = KeyName;
    
            // Добавляем элемент KeyInfoName к
            // объекту EncryptedKey.
            ek.KeyInfo.AddClause(kin);
    
            // Добавляем зашифрованные данные 
            // к объекту EncryptedData.
            edElement.CipherData.CipherValue = encryptedElement;
    
            // Заменяем исходный узел на зашифрованный.
            CpEncryptedXml.ReplaceElement(elementToEncrypt,
                edElement, false);
    
            // Сохраняем зашифрованный документ.
            xmlDoc.Save(destName);
        }
    }
    
    // Зашифрование узла в адрес абонента, заданного сертификатом 
    // получателя.
    static void Encrypt(XmlDocument Doc, string xpath,
        CpX509Certificate2 Cert)
    {
        // Ищем заданный элемент для заширования.
        XmlElement elementToEncrypt = Doc.SelectSingleNode(xpath) as XmlElement;
        if (elementToEncrypt == null)
            throw new XmlException("Узел не найден");
    
        // Создаем объект CpEncryptedXml для  
        // шифрования XmlElement
        CpEncryptedXml eXml = new CpEncryptedXml();
    
        // Шифруем элемент на сертификате.
        CpEncryptedData edElement = eXml.Encrypt(elementToEncrypt, Cert);
    
        // Заменяем исходный элемент XML документа зашифрованным.
        CpEncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
    }
    
    // Тестовый документ для зашифрования / расшифрования.
    private static string SourceDocument = "" +
        "<MyXML Encrypted=\"false\">" +
        "    <SomeNode ToEncrypt=\"false\">" +
                "Here is some public data.</SomeNode>" +
        "    <SomeNode ToEncrypt=\"true\">" +
                "Here is some data to encrypt.</SomeNode>" +
        "</MyXML>";
    
    // Создание тестового XML документа.
    static void CreateSomeXml(string FileName)
    {
        // Создать документ по строке
        XmlDocument document = new XmlDocument();
        document.LoadXml(SourceDocument);
    
        // Сохранить шифруемый документ в файле.
        using (XmlTextWriter xmltw = new XmlTextWriter(FileName,
            new UTF8Encoding(false)))
        {
            xmltw.WriteStartDocument();
            document.WriteTo(xmltw);
        }
    }
    
    В этом разделе
    Наверх Generated by DocFX