using GostCryptography.Base;
using GostCryptography.Config;
using GostCryptography.Gost_28147_89;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Security.Policy;
using System.Text;
using System.Xml;
namespace GostCryptography.Xml
{
///
/// Объект для шифрации и дешифрации XML по ГОСТ 34.10
///
public sealed class GostEncryptedXml
{
///
/// URI пространства имен для синтаксиса и правил обработки при шифровании XML по ГОСТ
///
public const string XmlEncGostNamespaceUrl = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:";
///
/// URI алгоритма экспорта ключа по ГОСТ 28147-89
///
public const string XmlEncGostKeyExportUrl = XmlEncGostNamespaceUrl + "kw-gost";
///
/// URI алгоритма экспорта ключа КриптоПро
///
public const string XmlEncGostCryptoProKeyExportUrl = XmlEncGostNamespaceUrl + "kw-cp";
static GostEncryptedXml()
{
GostCryptoConfig.Initialize();
}
///
public GostEncryptedXml() : this(GostCryptoConfig.ProviderType)
{
}
///
public GostEncryptedXml(ProviderType providerType)
{
_encryptedXml = new GostEncryptedXmlImpl(providerType);
}
///
public GostEncryptedXml(XmlDocument document) : this(GostCryptoConfig.ProviderType, document)
{
}
///
public GostEncryptedXml(ProviderType providerType, XmlDocument document)
{
_encryptedXml = new GostEncryptedXmlImpl(providerType, document);
}
///
public GostEncryptedXml(XmlDocument document, Evidence evidence) : this(GostCryptoConfig.ProviderType, document, evidence)
{
}
///
public GostEncryptedXml(ProviderType providerType, XmlDocument document, Evidence evidence)
{
_encryptedXml = new GostEncryptedXmlImpl(providerType, document, evidence);
}
private readonly GostEncryptedXmlImpl _encryptedXml;
///
public Evidence DocumentEvidence
{
get => _encryptedXml.DocumentEvidence;
set => _encryptedXml.DocumentEvidence = value;
}
///
public XmlResolver Resolver
{
get => _encryptedXml.Resolver;
set => _encryptedXml.Resolver = value;
}
///
public PaddingMode Padding
{
get => _encryptedXml.Padding;
set => _encryptedXml.Padding = value;
}
///
public CipherMode Mode
{
get => _encryptedXml.Mode;
set => _encryptedXml.Mode = value;
}
///
public Encoding Encoding
{
get => _encryptedXml.Encoding;
set => _encryptedXml.Encoding = value;
}
///
public string Recipient
{
get => _encryptedXml.Recipient;
set => _encryptedXml.Recipient = value;
}
// Encryption
///
/// Шифрует XML-элемент с помощью ключа с указанным именем
///
/// Шифруемый XML-элемент
/// Имя ключа для шифрования XML-элемента
/// Зашифрованное представление XML-элемента
public EncryptedData Encrypt(XmlElement element, string keyName)
{
return _encryptedXml.Encrypt(element, keyName);
}
///
/// Шифрует XML-элемент с помощью сертификата
///
/// Шифруемый XML-элемент
/// Сертификат X.509 для шифрования XML-элемента
/// Зашифрованное представление XML-элемента
public EncryptedData Encrypt(XmlElement element, X509Certificate2 certificate)
{
return _encryptedXml.Encrypt(element, certificate);
}
///
/// Шифрует данные с помощью указанного симметричного ключа
///
/// Шифруемые данные
/// Симметричный ключ для шифрования данных
/// Массив байт, содержащий зашифрованные данные
public byte[] EncryptData(byte[] data, SymmetricAlgorithm symmetricKey)
{
return _encryptedXml.EncryptData(data, symmetricKey);
}
///
/// Шифрует XML-элемент с помощью указанного симметричного ключа
///
/// Шифруемый XML-элемент
/// Симметричный ключ для шифрования XML-элемента
/// Значение true для шифрования только содержимого элемента; значение false для шифрования всего элемента
/// Массив байт, содержащий зашифрованные данные
public byte[] EncryptData(XmlElement element, SymmetricAlgorithm symmetricKey, bool content)
{
return _encryptedXml.EncryptData(element, symmetricKey, content);
}
///
/// Шифрует сессионный ключ с помощью указанного общего симметричного ключа
///
/// Шифруемый сессионный ключ
/// Общий симметричный ключ для шифрования сессионного ключа
/// Массив байт, содержащий зашифрованный сессионный ключ
/// Как правило сессионный ключ используется для шифрования данных и в свою очередь так же шифруется
public static byte[] EncryptKey(byte[] keyData, SymmetricAlgorithm sharedKey)
{
return EncryptedXml.EncryptKey(keyData, sharedKey);
}
///
/// Шифрует сессионный ключ с помощью указанного асимметричного ключа RSA
///
/// Шифруемый сессионный ключ
/// Открытый ключ RSA для шифрования сессионного ключа
/// Значение, указывающее, следует ли использовать заполнение OAEP (Optimal Asymmetric Encryption Padding)
/// Массив байт, содержащий зашифрованный сессионный ключ
/// Как правило сессионный ключ используется для шифрования данных и в свою очередь так же шифруется
public static byte[] EncryptKey(byte[] keyData, RSA publicKey, bool useOaep)
{
return EncryptedXml.EncryptKey(keyData, publicKey, useOaep);
}
///
/// Шифрует сессионный ключ с помощью указанного асимметричного ключа ГОСТ Р 34.10
///
/// Шифруемый сессионный ключ
/// Открытый ключ ГОСТ Р 34.10 для шифрования сессионного ключа
/// Массив байт, содержащий зашифрованный сессионный ключ
/// Как правило сессионный ключ используется для шифрования данных и в свою очередь так же шифруется
public static byte[] EncryptKey(Gost_28147_89_SymmetricAlgorithmBase sessionKey, GostAsymmetricAlgorithm publicKey)
{
return GostEncryptedXmlImpl.EncryptKey(sessionKey, publicKey);
}
///
/// Шифрует сессионный ключ с помощью указанного симметричного ключа ГОСТ 28147
///
/// Шифруемый сессионный ключ
/// Общий симметричный ключ ГОСТ 28147 для шифрования сессионного ключа
/// Алгоритм экспорта сессионного ключа
/// Массив байт, содержащий зашифрованный сессионный ключ
/// Как правило сессионный ключ используется для шифрования данных и в свою очередь так же шифруется
public static byte[] EncryptKey(Gost_28147_89_SymmetricAlgorithmBase sessionKey, Gost_28147_89_SymmetricAlgorithmBase sharedKey, GostKeyExchangeExportMethod exportMethod = GostKeyExchangeExportMethod.GostKeyExport)
{
return GostEncryptedXmlImpl.EncryptKey(sessionKey, sharedKey, exportMethod);
}
///
/// Расшифровывает зашифрованный XML-элемент с помощью указанного симметричного ключа
///
/// Зашифрованное представление XML-элемента
/// Симметричный ключ для расшифровки данных
/// Массив байт, содержащий расшифрованный XML-элемент
public byte[] DecryptData(EncryptedData encryptedData, SymmetricAlgorithm symmetricKey)
{
return _encryptedXml.DecryptData(encryptedData, symmetricKey);
}
///
/// Расшифровывает все зашифрованные XML-элементы документа
///
public void DecryptDocument()
{
_encryptedXml.DecryptDocument();
}
///
/// Возвращает вектор инициализации для расшифровки XML-элемента
///
/// Зашифрованное представление XML-элемента
/// URI алгоритма шифрования
/// Массив байт, содержащий вектор инициализации для расшифровки XML-элемента
public byte[] GetDecryptionIV(EncryptedData encryptedData, string symmetricAlgorithmUri)
{
return _encryptedXml.GetDecryptionIV(encryptedData, symmetricAlgorithmUri);
}
///
/// Возвращает симметричный ключ для расшифровки XML-элемента
///
/// Зашифрованное представление XML-элемента
/// URI алгоритма шифрования
/// Симметричный ключ для расшифровки XML-элемента
public SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri)
{
return _encryptedXml.GetDecryptionKey(encryptedData, symmetricAlgorithmUri);
}
///
/// Извлекает ключ из элемента <EncryptedKey>
///
/// Элемент <EncryptedKey> с информацией о ключе шифрования
/// Массив байт, содержащий ключ для расшифровки
public byte[] DecryptEncryptedKey(EncryptedKey encryptedKey)
{
return _encryptedXml.DecryptEncryptedKey(encryptedKey);
}
///
/// Расшифровывает сессионный ключ с помощью указанного общего симметричного ключа
///
/// Массив байт, содержащий зашифрованный сессионный ключ
/// Общий симметричный ключ для расшифровки сессионного ключа
/// Массив байт, который содержит сессионный ключ
/// Как правило сессионный ключ используется для шифрования данных и в свою очередь так же шифруется
public static byte[] DecryptKey(byte[] keyData, SymmetricAlgorithm sharedKey)
{
return EncryptedXml.EncryptKey(keyData, sharedKey);
}
///
/// Расшифровывает сессионный ключ с помощью указанного асимметричного ключа RSA
///
/// Массив байт, содержащий зашифрованный сессионный ключ
/// Закрытый ключ RSA для расшифровки сессионного ключа
/// Значение, указывающее, следует ли использовать заполнение OAEP (Optimal Asymmetric Encryption Padding)
/// Массив байт, который содержит сессионный ключ
/// Как правило сессионный ключ используется для шифрования данных и в свою очередь так же шифруется
public static byte[] DecryptKey(byte[] keyData, RSA privateKey, bool useOaep)
{
return EncryptedXml.DecryptKey(keyData, privateKey, useOaep);
}
///
/// Расшифровывает сессионный ключ с помощью указанного асимметричного ключа ГОСТ Р 34.10
///
/// Массив байт, содержащий зашифрованный сессионный ключ
/// Закрытый ключ ГОСТ Р 34.10 для расшифровки сессионного ключа
/// Сессионный ключ
/// Как правило сессионный ключ используется для шифрования данных и в свою очередь так же шифруется
public static SymmetricAlgorithm DecryptKey(byte[] keyData, GostAsymmetricAlgorithm privateKey)
{
return GostEncryptedXmlImpl.DecryptKeyClass(keyData, privateKey);
}
///
/// Заменяет указанный зашифрованный XML-элемент его расшифрованным представлением
///
/// Заменяемый зашифрованный XML-элемент
/// Расшифрованное представление XML-элемента
public void ReplaceData(XmlElement element, byte[] decryptedData)
{
_encryptedXml.ReplaceData(element, decryptedData);
}
///
/// Заменяет указанный XML-элемент его зашифрованным представлением
///
/// Заменяемый XML-элемент
/// Зашифрованное представление XML-элемента
/// Значение true для замены только содержимого элемента; значение false для замены всего элемента
public static void ReplaceElement(XmlElement element, EncryptedData encryptedData, bool content)
{
EncryptedXml.ReplaceElement(element, encryptedData, content);
}
///
/// Возвращает XML-элемент с указанным идентификатором
///
/// Документ для поиска идентификатора XML-элемента
/// Значение идентификатора XML-элемента
public XmlElement GetIdElement(XmlDocument document, string idValue)
{
return _encryptedXml.GetIdElement(document, idValue);
}
///
/// Сопоставляет имя ключа шифрования со значением
///
/// Имя ключа шифрования
/// Значение ключа шифрования
public void AddKeyNameMapping(string keyName, object keyObject)
{
_encryptedXml.AddKeyNameMapping(keyName, keyObject);
}
///
/// Сбрасывает все сопоставления между именами и ключами шифрования
///
public void ClearKeyNameMappings()
{
_encryptedXml.ClearKeyNameMappings();
}
}
}