Closed AshurkovAV closed 5 years ago
Здравствуйте. Лично у меня нет, но какие-то примеры были в Issues. Посмотрите, может что-то найдете.
Спасибо, за ответ. Пока не могу найти. Возможно нужно еще покопаться.
Подскажите еще одни вопрос. Как явно установить
Вопрос снят разобрался
Добрый день. Не получается отправить зашифрованное подписанное сообщение в ФСС. Сертификат - ГОСТ-2012 256 бит. Отправить тестовое подписанное сообщение - получается. Тестовое зашифрованное - нет. При отправке из кода C# получаю 500 ошибку. Если отправлять через SoapUI, выдается:
Теперь пробую через GostCryptography с описанным тут примером. Подскажите, пожалуйста, что не так с шифрованием?
public static XmlDocument EncryptionXML(XmlDocument document, X509Certificate2 cert)
{
document.PreserveWhitespace = true;
XmlNode elementBody = document.GetElementsByTagName("Envelope", Vars.xmlns_soapenv)[0];
// Создаем новый XML документ.
XmlDocument doc = new XmlDocument();
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("soapenv", Vars.xmlns_soapenv);
ns.AddNamespace("xenc", Vars.xmlns_xenc);
ns.AddNamespace("ds", Vars.xmlns_ds);
ns.AddNamespace("sch", Vars.xmlns_sch);
ns.AddNamespace("wsse", Vars.xmlns_wsse);
ns.AddNamespace("wsu", Vars.xmlns_wsu);
MemoryStream newRequestStream = new MemoryStream();
XmlWriter writer = XmlWriter.Create(newRequestStream, new XmlWriterSettings { Encoding = Encoding.UTF8 });
writer.WriteStartDocument();
// Envelope
writer.WriteStartElement("soapenv", "Envelope", Vars.xmlns_soapenv);
//Header
writer.WriteStartElement("soapenv", "Header", Vars.xmlns_soapenv);
writer.WriteEndElement(); // Header
writer.WriteStartElement("soapenv", "Body", Vars.xmlns_soapenv); // Body
// ************************************************************* EncryptedData ************************************************************************** /
writer.WriteRaw(elementBody.OuterXml);
// ******************************************************************************************************************************************************* /
writer.WriteEndElement(); // Body
writer.WriteEndElement(); // Envelope
writer.WriteEndDocument();
writer.Flush();
string xmlText = Encoding.GetEncoding("UTF-8").GetString(newRequestStream.ToArray());
XmlDocument xml = new XmlDocument();
newRequestStream.Position = 0;
xml.Load(newRequestStream);
writer.Close();
// Ищем заданный элемент для зашифрования. Envelope
XmlElement elementToEncrypt = xml.GetElementsByTagName("Envelope", Vars.xmlns_soapenv)[1] as XmlElement;
if (elementToEncrypt == null)
throw new XmlException("Узел не найден");
// Создаем объект EncryptedData и заполняем его необходимой информацией.
EncryptedData elementEncryptedData = new EncryptedData();
elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl;
// Созданный элемент помечаем EncryptedElement1
//elementEncryptedData.Id = "EncryptedElement1";
elementEncryptedData.KeyInfo = new KeyInfo();
// Созданный элемент помечаем EncryptedElement1
// edElement.Id = "EncryptedElement1";
using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm(ProviderType.CryptoPro_2012_512))
{
EncryptedXml encryptedXml = new EncryptedXml();
// Шифрация элемента с использованием симметричного ключа
var encryptedElement = encryptedXml.EncryptData(elementToEncrypt, sessionKey, false);
// Шифрация сессионного ключа с использованием открытого ключа сертификата
var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, (GostAsymmetricAlgorithm)cert.GetPublicKeyAlgorithm());
// Формирование информации о зашифрованном сессионном ключе
var encryptedSessionKey = new EncryptedKey();
encryptedSessionKey.CipherData = new CipherData(encryptedSessionKeyData);
encryptedSessionKey.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGostNamespaceUrl + "transport-gost2001");
//encryptedSessionKey.AddReference(new DataReference { Uri = "#" + elementEncryptedData.Id });
encryptedSessionKey.KeyInfo.AddClause(new KeyInfoX509Data(cert));
// Добавление ссылки на зашифрованный ключ, используемый при шифровании данных
elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));
// Установка зашифрованных данных у объекта EncryptedData
elementEncryptedData.CipherData.CipherValue = encryptedElement;
}
// Заменяем исходный узел на зашифрованный.
EncryptedXml.ReplaceElement(elementToEncrypt, elementEncryptedData, false);
return xml;
}
Добрый день. Не получается отправить зашифрованное подписанное сообщение в ФСС.
Отравил вам на почту пример шифрования
Алексей, здравствуйте! В этом письме нет приложенного файла. Отправьте, пожалуйста, еще раз. Заранее спасибо!
Воскресенье, 3 ноября 2019, 0:42 +05:00 от AshurkovAV notifications@github.com: Добрый день. Не получается отправить зашифрованное подписанное сообщение в ФСС. Отравил вам на почту пример шифрования — You are receiving this because you commented. Reply to this email directly, view it on GitHub , or unsubscribe .
Александр D.
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, Gost_28147_89_SymmetricAlgorithmBase sharedKey,
X509Certificate2 certificateEncryption,
X509Certificate2 certificateOpen)
{
// Ищем заданный элемент для заширования. Envelope
XmlElement elementToEncrypt = xmlDocument.GetElementsByTagName("Envelope", Constants.xmlns_soapenv)[1] as XmlElement;
// Создаем объект EncryptedData и заполняем его необходимой информацией.
EncryptedData edElement = new EncryptedData();
edElement.Type = EncryptedXml.XmlEncElementUrl;
// Созданный элемент помечаем EncryptedElement1
//edElement.Id = "EncryptedElement1";
// Заполняем алгоритм зашифрования данных. Он будет использован при расшифровании.
edElement.EncryptionMethod = new EncryptionMethod(Gost_28147_89_SymmetricAlgorithm.AlgorithmNameValue);
// Создаем новую ссылку на ключ.
edElement.KeyInfo = new KeyInfo();
// Создаем случайный симметричный ключ.
// В целях безопасности удаляем ключ из памяти после использования.
using (Gost_28147_89_SymmetricAlgorithm sessionKey = new Gost_28147_89_SymmetricAlgorithm(sharedKey.ProviderType))
{
//При генерации сессионного ключа 28147 всегда используется 2001 провайдер(TypeId = 75).
//Соответственно параметры CIPHER_OID ключа всегда берутся для указанного провайдера.
//И если при шифровании ключа используется новый сертификат ФСС(уполномоченного лица) с
//2012 ключом получается нехорошо:
// -(.
//В обернутом ключе параметры алгоритма прописываются
//1.2.643.2.2.31.1
//когда как ФСС ожидает
//1.2.643.7.1.2.5.1.1
// Создаем объект класса EncryptedXml
EncryptedXml eXml = new EncryptedXml();
// Зашифроваем узел на симметричном ключе.
byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false);
// Зашифровываем сессионный ключ и добавляем эти зашифрованные данные к узлу EncryptedKey.
EncryptedKey ek = new EncryptedKey();
byte[] encryptedKey = GostEncryptedXml.EncryptKey(sessionKey, (GostAsymmetricAlgorithm)certificateEncryption.GetPublicKeyAlgorithm());
ek.CipherData = new CipherData(encryptedKey);
ek.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGostNamespaceUrl + "transport-gost2001");
KeyInfoX509Data data = new KeyInfoX509Data(certificateOpen);
ek.KeyInfo.AddClause(data);
// Добавляем ссылку на зашифрованный ключ к зашифрованным данным.
edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
// Добавляем зашифрованные данные к объекту EncryptedData.
edElement.CipherData.CipherValue = encryptedElement;
}
// Заменяем исходный узел на зашифрованный.
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
return xmlDocument;
}
/// <summary>
/// Расшифровываем полученные данные от ФСС
/// </summary>
/// <param name="document"></param>
/// <returns></returns>
public string DecryptXmlDocument(string document)
{
// Создаем объект XmlDocument.
XmlDocument xmlDoc = new XmlDocument();
// Загружаем XML файл в объект XmlDocument.
xmlDoc.PreserveWhitespace = true;
xmlDoc.LoadXml(document);
// Ищем все зашифрованные данные.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("enc", "http://www.w3.org/2001/04/xmlenc#");
XmlNodeList list = xmlDoc.SelectNodes("//enc:EncryptedData", nsmgr);
// Создаем объект EncryptedXml.
GostEncryptedXml exml = new GostEncryptedXml(xmlDoc);
if (list != null)
{
// Для всех зашифрованных данных.
foreach (XmlNode node in list)
{
XmlElement element = node as XmlElement;
EncryptedData encryptedData = new EncryptedData();
encryptedData.LoadXml(element);
// Находим подходящий ключ для расшифрования.
SymmetricAlgorithm decryptionKey = GetDecryptionKeyVipNet(encryptedData);
if (decryptionKey == null)
{
throw new Exception("Ключ для расшифрования сообщения не найден.");
}
// И на нем расшифровываем данные.
byte[] decryptedData = exml.DecryptData(encryptedData, decryptionKey);
exml.ReplaceData(element, decryptedData);
}
}
return xmlDoc.OuterXml;
}
private static SymmetricAlgorithm GetDecryptionKeyVipNet(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;
var keyContainer = Constants.CertificateMo.GetPrivateKeyInfo();
// Приватный ключ, открытый ключ которого мы отправляли при шифровании запроса
var privateKey = new Gost_R3410_2012_256_AsymmetricAlgorithm(keyContainer);
// Приватный ключ, открытый ключ которого мы отправляли при шифровании запроса
Gost_R3410_2012_256_AsymmetricAlgorithm myKey = privateKey as Gost_R3410_2012_256_AsymmetricAlgorithm;
if (myKey == null)
continue;
return GostEncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, myKey);
}
}
return null;
}
Это расшифровка
Спасибо! Мир не без добрых людей. Неделю мучаюсь. Во вторник попробую отправить в ФСС. sharedKey — это откуда можно взять? certificateEncryption — это личный сертификат? certificateOpen — это сертификат уполномоченного ФСС?
Воскресенье, 3 ноября 2019, 0:55 +05:00 от AshurkovAV notifications@github.com: private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, Gost_28147_89_SymmetricAlgorithmBase sharedKey, X509Certificate2 certificateEncryption, X509Certificate2 certificateOpen) { // Ищем заданный элемент для заширования. Envelope XmlElement elementToEncrypt = xmlDocument.GetElementsByTagName("Envelope", Constants.xmlns_soapenv)[1] as XmlElement; // Создаем объект EncryptedData и заполняем его необходимой информацией. EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; // Созданный элемент помечаем EncryptedElement1 //edElement.Id = "EncryptedElement1"; // Заполняем алгоритм зашифрования данных. Он будет использован при расшифровании. edElement.EncryptionMethod = new EncryptionMethod(Gost_28147_89_SymmetricAlgorithm.AlgorithmNameValue);
// Создаем новую ссылку на ключ. edElement.KeyInfo = new KeyInfo(); // Создаем случайный симметричный ключ. // В целях безопасности удаляем ключ из памяти после использования. using (Gost_28147_89_SymmetricAlgorithm sessionKey = new Gost_28147_89_SymmetricAlgorithm(sharedKey.ProviderType)) { //При генерации сессионного ключа 28147 всегда используется 2001 провайдер(TypeId = 75). //Соответственно параметры CIPHER_OID ключа всегда берутся для указанного провайдера. //И если при шифровании ключа используется новый сертификат ФСС(уполномоченного лица) с //2012 ключом получается нехорошо: // -(. //В обернутом ключе параметры алгоритма прописываются //1.2.643.2.2.31.1 //когда как ФСС ожидает //1.2.643.7.1.2.5.1.1 // Создаем объект класса EncryptedXml EncryptedXml eXml = new EncryptedXml(); // Зашифроваем узел на симметричном ключе. byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false); // Зашифровываем сессионный ключ и добавляем эти зашифрованные данные к узлу EncryptedKey. EncryptedKey ek = new EncryptedKey(); byte[] encryptedKey = GostEncryptedXml.EncryptKey(sessionKey, (GostAsymmetricAlgorithm)certificateEncryption.GetPublicKeyAlgorithm()); ek.CipherData = new CipherData(encryptedKey); ek.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGostNamespaceUrl + "transport-gost2001"); KeyInfoX509Data data = new KeyInfoX509Data(certificateOpen); ek.KeyInfo.AddClause(data); // Добавляем ссылку на зашифрованный ключ к зашифрованным данным. edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek)); // Добавляем зашифрованные данные к объекту EncryptedData. edElement.CipherData.CipherValue = encryptedElement; } // Заменяем исходный узел на зашифрованный. EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); return xmlDocument; }
— You are receiving this because you commented. Reply to this email directly, view it on GitHub , or unsubscribe .
Александр D.
ProviderType providerType = ProviderType.VipNet; var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType); X509Certificate2 certificateEncryption, - сертификат фсс X509Certificate2 certificateOpen - сертификат медицинской организации
Спасибо!
Воскресенье, 3 ноября 2019, 22:11 +05:00 от AshurkovAV notifications@github.com: ProviderType providerType = ProviderType.VipNet; var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType); X509Certificate2 certificateEncryption, - сертификат фсс X509Certificate2 certificateOpen - сертификат медицинской организации — You are receiving this because you commented. Reply to this email directly, view it on GitHub , or unsubscribe .
Александр D.
Добрый день. Не получается отправить зашифрованное подписанное сообщение в ФСС.
Отравил вам на почту пример шифрования Добрый день, можно мне тоже отправить пример ?
Gost_28147_89_SymmetricAlgorithm
Я не нашел отличий в вашем коде и @alexnur
В чем фишка? У меня таже проблема с сертификатом фсс 2012
Можно код в почту?
Gost_28147_89_SymmetricAlgorithm
Я не нашел отличий в вашем коде и @alexnur В чем фишка? У меня таже проблема с сертификатом фсс 2012 Можно код в почту?
Добрый день, данную тему хорошо осветили в новой ветке
https://github.com/AlexMAS/GostCryptography/issues/39
Gost_28147_89_SymmetricAlgorithm
Я не нашел отличий в вашем коде и @alexnur В чем фишка? У меня таже проблема с сертификатом фсс 2012 Можно код в почту?
Добрый день, подскажите есть пример шифрования запроса на сервис ФСС под ГОСТ 2012