alexmas / gostcryptography Goto Github PK
View Code? Open in Web Editor NEW.NET driver for ViPNet CSP and CryptoPro CSP
License: MIT License
.NET driver for ViPNet CSP and CryptoPro CSP
License: MIT License
Здравствуйте, Александр.
Пробую использовать вашу библиотеку в сервисе на IIS.
При дешифрации использовал пример из https://github.com/AlexMAS/GostCryptography/tree/master/Source/GostCryptography.Tests
var encryptedXml= new GostEncryptedXml(doc);
encryptedXml.AddKeyNameMapping("KeyName1", privateKey); /* Добавляю ссылку на приватный ассиметричный ключ с установленным privateKey.SetContainerPassword(secureString); /
encryptedXml.DecryptDocument(); / Но на этапе дешифровки криптопровайдер всё равно запрашивает выводит окно для указания пароля для сертификата */
Возможно ли установить пароль для контейнера сертификата программно без вывода на экран окна криптопровайдера при дешифрации (сертификаты находятся в локальном хранилище компьютера)?
Добрый день!
Планируется ли такая возможность?
День добрый.
Имеется примерно следующий файл
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:GetResponseResponse
xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.2"
xmlns:ns2="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.2"
xmlns:ns3="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/faults/1.2">
<ns2:ResponseMessage>
<ns2:Response Id="SIGNED_BY_SMEV">
...
<ns2:SenderInformationSystemSignature>
<Signature:Signature
xmlns:Signature="http://www.w3.org/2000/09/xmldsig#"
xmlns="http://www.w3.org/2000/09/xmldsig#" Id="">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256" />
<Reference Id="" URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<Transform Algorithm="urn://smev-gov-ru/xmldsig/transform" />
</Transforms>
<DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256" />
<DigestValue>...</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>...</SignatureValue>
<KeyInfo Id="">
<X509Data>
<X509Certificate>Серт_1</X509Certificate>
</X509Data>
</KeyInfo>
</Signature:Signature>
</ns2:SenderInformationSystemSignature>
</ns2:Response>
<ns2:SMEVSignature>
<ds:Signature
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
...
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>Серт_2</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
</ns2:SMEVSignature>
</ns2:ResponseMessage>
</ns2:GetResponseResponse>
</soap:Body>
</soap:Envelope>
Который хранит в себе два сертификата.
Вопрос: как проверить эти оба сертефиката на виладность?
Моя попытка:
При проверке сигнатуры вторая сигнатура выдает false
Код метода verify
XmlDocument signedSmevRequest = CreateSmevRequest(xml);
GostSignedXml signedXml = new GostSignedXml(signedSmevRequest) { GetIdElementHandler = GetSmevIdElement };
bool isValid = signedSmevRequest.GetElementsByTagName("Signature", "http://www.w3.org/2000/09/xmldsig#")
.OfType<XmlElement>()
.ToArray()
.All(e =>
{
//workaround - remove the signature element here.
e.ParentNode?.RemoveChild(e);
signedXml.LoadXml(e);
XmlNodeList references = signedXml.KeyInfo.GetXml().GetElementsByTagName("X509Certificate");
X509Certificate2 certificate = new X509Certificate2(Convert.FromBase64String(references[0].InnerText));
bool valid = signedXml.CheckSignature(certificate.GetPublicKeyAlgorithm());
return valid;
});
return isValid;
Здравствуйте, при использовании вашей библиотеки в проекте, где используется WCF-сервис, требующий CryptoPro.NET, возникает ошибка: Parameter must support GOST R 34.10 algorithm.
Server stack trace:
в GostCryptography.Base.GostSignatureFormatter.SetKey(AsymmetricAlgorithm privateKey)
в System.Security.Cryptography.SignatureDescription.CreateFormatter(AsymmetricAlgorithm key)
в System.IdentityModel.Tokens.X509AsymmetricSecurityKey.GetSignatureFormatter(String algorithm)
в CryptoPro.Sharpei.IdentityModel.CPX509AsymmetricSecurityKey.GetSignatureFormatter(String algorithm)
в System.IdentityModel.SignedXml.ComputeSignature(SecurityKey signingKey)
в System.ServiceModel.Security.WSSecurityOneDotZeroSendSecurityHeader.CreateSupportingSignature(SecurityToken token, SecurityKeyIdentifier identifier, ISecurityElement elementToSign)
в System.ServiceModel.Security.SendSecurityHeader.SignWithSupportingToken(SecurityToken token, SecurityKeyIdentifierClause identifierClause)
в System.ServiceModel.Security.SendSecurityHeader.SignWithSupportingTokens()
в CryptoPro.Sharpei.ServiceModel.CPSendSecurityHeader.SignWithSupportingTokens()
в System.ServiceModel.Security.SendSecurityHeader.CompleteSecurityApplication()
в System.ServiceModel.Security.SecurityAppliedMessage.OnWriteMessage(XmlDictionaryWriter writer)
в System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(Message message, BufferManager bufferManager, Int32 initialOffset, Int32 maxSizeQuota)
в System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
в System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message, Boolean shouldRecycleBuffer)
в System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)
в System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.SendRequest(Message message, TimeSpan timeout)
в System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
в System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
в System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)
в System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
в CryptoPro.Sharpei.ServiceModel.CPSecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
в System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
в System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
в System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
в System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
в System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
в System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
в System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
в System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
в System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
в System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Последовательность работы такая: с помощью вашей библиотеки подписывается XML-файл по ГОСТ 34.10-2012 (длина ключа 256 бит), после чего осуществляется обращение к WCF-сервису. Сообщение успешно подписывается вашей библиотекой, но при обращении к WCF-сервису возникает ошибка. При использовании WCF в отдельном проекте проблема не наблюдается. Если важно, то WCF и подпись - это разные проекты, используется in-process side-by-side execution (основной проект на .NET 3.5, эти проекты на .NET 4.0).
CryptoPro CSP: 4.0.9842
CryptoPro.NET - 1.0.6893
Добрый день.
Пробую реализовать обмен пакетами содержащими имитовставки.
Подскажите, пожалуйста, как можно расшарить симметричный ключ между двумя сервисами для тестов? Аналогично вот этому коду?
public void ShouldComputeHMAC(ProviderType providerType)
{
// Given
var dataStream = CreateDataStream();
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
// When
var hmacDataStream = CreateHmacDataStream(sharedKey, dataStream);
var isValidHmacDataStream = VerifyHmacDataStream(sharedKey, hmacDataStream);
// Then
Assert.IsTrue(isValidHmacDataStream);
}
К сожалению- не имею совершенно не имею опыта в криптографии.
Добрый день. При попытке задать пароль для контейнера закрытого ключа получаю исключение:
Методу "GostCryptography.Gost_R3410.Gost_R3410_AsymmetricAlgorithm`2<TKeyParams,TKeyAlgorithm>.SetSignatureKeyPassword(GostCryptography.Native.SafeProvHandleImpl,
System.Security.SecureString, Int32)", прозрачному для безопасности, не удалось получить доступ к критически важному типу безопасности "GostCryptography.Native.SafeProvHandleImpl".
Сборка "GostCryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" помечена атрибутом AllowPartiallyTrustedCallersAttribute и использует модель прозрачности безопасности уровня 2. Прозрачность уровня 2 делает все методы в сборках AllowPartiallyTrustedCallers прозрачными для безопасности по умолчанию, что может являться причиной этого исключения.
Пример кода:
var pars = x509Certificate.GetPrivateKeyInfo();
var gostR3410alg = new Gost_R3410_2001_AsymmetricAlgorithm(pars);
gostR3410alg.SetContainerPassword(s); // s - SecureString
return gostR3410alg; // Ошибка
Может быть я делаю что-то не так и есть какой-то другой способ? В прошлой версии это работало. Аналогичная ошибка и для Gost_R3410_2012_256_AsymmetricAlgorithm и Gost_R3410_2012_512_AsymmetricAlgorithm
День добрый.
Просто хотелось бы уточнить: проверялась ли работа библиотеки при одновременной установке в системе обоих криптопровайдеров?
При следующем вызове:
using (var gost28147 = new Gost_28147_89_SymmetricAlgorithm(provider.ProviderType)) {
var encryptedData = new GostEncryptedXml(provider.ProviderType).EncryptData(xmlElement, gost28147, false);
var encryptedKey = GostEncryptedXml.EncryptKey(
gost28147,
(GostAsymmetricAlgorithm)receiverCertificate.GetPublicKeyAlgorithm()
);
}
У меня возникает вот такая ситуация:
System.Security.Cryptography.CryptographicException : Плохой ключ.
в GostCryptography.Native.CryptoApiHelper.ExportCspBlob(SafeKeyHandleImpl symKeyHandle, SafeKeyHandleImpl keyExchangeHandle, Int32 blobType)
в GostCryptography.Gost_R3410.Gost_R3410_KeyExchangeAlgorithm.EncodeKeyExchangeInternal(Gost_28147_89_SymmetricAlgorithm keyExchangeAlgorithm, Int32 keyExchangeExportAlgId)
в GostCryptography.Gost_R3410.Gost_R3410_KeyExchangeFormatter3.CreateKeyExchangeInfo(SymmetricAlgorithm keyExchangeAlgorithm) в GostCryptography.Gost_R3410.Gost_R3410_KeyExchangeFormatter
3.CreateKeyExchangeData(SymmetricAlgorithm keyExchangeAlgorithm)
Причём речь идёт только про КриптоПро. ВипНет работает без проблем. Если удалить ВипНет из системы, то начинает работать и КриптоПро. 2001 или 2012 ГОСТ значения не имеет.
В связи с выходом новой версии СМЭВ было бы неплохо обновить SmevExample.xml SignedXmlSmevTest.cs в GostCryptography.Tests
День добрый!
Используем Вашу библиотеку, наверное единственное что удалось найти на просторах интернета для подписи с использованием сертификата GOST 3410 в среде Windows. Задача: осуществить взаимодействие с фед. сервисами.
В описании указано:
Требования к формированию токена, подписанного сертификатом ГОСТ Р 34.10-2012
1. Подпись токена (signature) должна быть сформирована в формате pkcs#7. При этом для подписи необходимо оставить только блок SignerInfo и убрать из нее данные сертификата;
2. В заголовке токена (Header) в блок “x5c” не нужно помещать всю цепочку сертификатов так как это влечет за собой превышение лимита длины заголовка запроса.
В итоге получаем при любом раскладе ошибку "GW-059: Неверное значение закодированной формы токена".
Более детальной информации, к сожалению не удается узнать, что не так в формируемом токене.
Окружение:
За основу взят пример https://github.com/AlexMAS/GostCryptography/blob/master/Source/GostCryptography.Tests/Pkcs/SignedCmsSignTest.cs
Исходный код (для облегчение и сокращения кода, часть кода убрана, суть остается):
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using GostCryptography.Base;
using GostCryptography.Gost_R3410;
var certStore = new X509Store(StoreLocation.CurrentUser);
certStore.Open(OpenFlags.ReadOnly);
var collection = certStore.Certificates;
var searchRes = collection.Find(X509FindType.FindBySerialNumber, serialNumber, false);
var cert = searchRes[0];
var alg = string.Empty;
switch (cert.PublicKey.Oid.Value)
{
case "1.2.643.2.2.19":
alg = "GOST3410-2001";
break;
case "1.2.643.7.1.1.1.1":
alg = "ECGOST3410-2012";
break;
case "1.2.643.7.1.1.1.2":
alg = "ECGOST3410-2012";
break;
}
JwtHeader header = new JwtHeader()
{
{ "alg", alg },
{ "x5c", Convert.ToBase64String(cert.GetRawCertData()) },
};
JwtPayload payload = new JwtPayload()
{
{ "sub", "CD28DB17-8A5E-4DDC-8C0B-0F6C10C9B041" }, /* произвольный гуид */
{ "aud", "http://ya.ru" }, /* произвольный адрес */
{ "iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds() },
{ "exp", DateTimeOffset.UtcNow.Add(new TimeSpan(0, 10, 0)).ToUnixTimeSeconds() }
};
JwtSecurityToken token = new JwtSecurityToken(header, payload);
string message = token.EncodedHeader + "." + token.EncodedPayload;
// Создание объекта для подписи сообщения
ContentInfo contentInfo = new ContentInfo(Encoding.UTF8.GetBytes(message));
GostCryptography.Pkcs.GostSignedCms signedCms = new GostCryptography.Pkcs.GostSignedCms(contentInfo);
// Создание объект с информацией о подписчике
CmsSigner cmsSigner = new CmsSigner(cert);
// Включение информации только о конечном сертификате (только для теста)
cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;
// Создание подписи для сообщения CMS/PKCS#7
signedCms.ComputeSignature(cmsSigner);
// Создание сообщения CMS/PKCS#7
byte[] signature = signedCms.Encode();
var encodedSignature = Microsoft.IdentityModel.Tokens.Base64UrlEncoder.Encode(signature);
var jwtToken = $"{message}.{encodedSignature}";
/* в итоге получаем токен из трех составляющих
token.EncodedHeader + "." + token.EncodedPayload + "." + encodedSignature */
И при обращении, при любом раскладе получаем ошибку:
"GW-059: Неверное значение закодированной формы токена".
Что конкретно не так в токене, выяснить не удается.
В описании имеется фраза: "и убрать из нее данные сертификата;" - пробовали делать signedCms.Certificates.Clear(); перед вызовом signedCms.Encode();, не помогает.
Не можем понять что может быть. Может у нас что-то не так недонастроено, или какой-то строки кода не хватает.
Или всё же пытаться выяснять что не так в формате.
Подскажите пожалуйста, что может быть, по какому пути идти ?
Здравствуйте, имеется WCF-сервис, разработанный сторонней компанией, и клиент. Для работы клиента требуется CryptoPro .NET, возможно ли использование вашей библиотеки вместо платного CryptoPro .NET?
Доброго дня!
Спасибо за продукт! Очень выручаете!
Хотел попросить рассмотреть возможность поддержки работы с префиксом на блок Signature лично столкнулся с проблемой на примере сервиса ГИИС ДМДК https://dmdk.ru они отступают от стандарта и требуют префикс причем только "ds" пока решил временным костылём но хочется видеть интегрированное в библиотеку, более изящное и лаконичное решение так как не имею опыта работы с xml прикладываю то, что у меня работает.
Работающий код:
`
public static void SignDmdkXml(string requestFileName, string requestSignedFileName,
X509Certificate2 certificate, bool saveFormat = true)
{
// Подгружаем документ
var xdoc = new XmlDocument
{
PreserveWhitespace = saveFormat
};
xdoc.Load(requestFileName);
// Создание подписчика XML-документа
var signedXml = new PrefixedSignedXml(xdoc,"ds")
{
// Установка ключа для создания подписи
SigningKey = certificate.PrivateKey,
SignedInfo =
{
// Установка алгоритма нормализации узла SignedInfo (в соответствии с методическими рекомендациями СМЭВ)
CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl,
// Установка алгоритма хэширования (в соответствии с методическими рекомендациями СМЭВ)
SignatureMethod = CPSignedXml.XmlDsigGost3410_2012_256Url
}
};
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
var dataReference = new Reference
{
Uri = "#body",
DigestMethod = CPSignedXml.XmlDsigGost3411_2012_256Url
};
// Метод преобразования, применяемый к данным перед их подписью (в соответствии с методическими рекомендациями СМЭВ)
dataReference.AddTransform(new XmlDsigExcC14NTransform());
dataReference.AddTransform(new XmlDsigSmevTransform());
signedXml.SafeCanonicalizationMethods.Add("urn://smev-gov-ru/xmldsig/transform");
// Установка ссылки на узел
signedXml.AddReference(dataReference);
// Установка информации о сертификате, который использовался для создания подписи
var keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(certificate));
signedXml.KeyInfo = keyInfo;
// Вычисление подписи
signedXml.ComputeSignature();
// Получение XML-представления подписи
var signatureXml = signedXml.GetXml();
//// Добавление подписи в исходный документ
xdoc.GetElementsByTagName("ns:CallerSignature")[0].AppendChild(xdoc.ImportNode(signatureXml, true));
// Охраняем документ в выходной файл
if (!saveFormat)
{
var settings = new XmlWriterSettings
{
Indent = false,
NewLineChars = Empty
};
using var writer = XmlWriter.Create(requestSignedFileName, settings);
xdoc.Save(writer);
}
else
xdoc.Save(requestSignedFileName);
}
}
`
Использую обвертку над XmlSigned:
`
///
public PrefixedSignedXml(XmlDocument document, string prefix)
: base(document)
{
_prefix = prefix;
}
public void ComputeSignature()
{
BuildDigestedReferences();
var signingKey = SigningKey;
if (signingKey == null)
{
throw new CryptographicException("Cryptography_Xml_LoadKeyFailed");
}
if (SignedInfo.SignatureMethod == null)
{
if (signingKey is not DSA)
{
if (signingKey is not RSA)
{
throw new CryptographicException("Cryptography_Xml_CreatedKeyFailed");
}
SignedInfo.SignatureMethod ??= "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
}
else
{
SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#dsa-sha1";
}
}
if (CryptoConfig.CreateFromName(SignedInfo.SignatureMethod) is not SignatureDescription description)
{
throw new CryptographicException("Cryptography_Xml_SignatureDescriptionNotCreated");
}
var hash = description.CreateDigest();
if (hash == null)
{
throw new CryptographicException("Cryptography_Xml_CreateHashAlgorithmFailed");
}
GetC14NDigest(hash, _prefix);
m_signature.SignatureValue = description.CreateFormatter(signingKey).CreateSignature(hash);
}
public new XmlElement GetXml()
{
var e = base.GetXml();
SetPrefix(_prefix, e);
return e;
}
//Отражательно вызывать закрытый метод SignedXml.BuildDigestedReferences
private void BuildDigestedReferences()
{
var t = typeof(SignedXml);
var m = t.GetMethod("BuildDigestedReferences", BindingFlags.NonPublic | BindingFlags.Instance);
m?.Invoke(this, new object[] { });
}
private void GetC14NDigest(HashAlgorithm hash, string prefix)
{
//string securityUrl = (this.m_containingDocument == null) ? null : this.m_containingDocument.BaseURI;
//XmlResolver xmlResolver = new XmlSecureResolver(new XmlUrlResolver(), securityUrl);
var document = new XmlDocument
{
PreserveWhitespace = true
};
var e = SignedInfo.GetXml();
document.AppendChild(document.ImportNode(e, true));
//CanonicalXmlNodeList namespaces = (this.m_context == null) ? null : Utils.GetPropagatedAttributes(this.m_context);
//Utils.AddNamespaces(document.DocumentElement, namespaces);
var canonicalizationMethodObject = SignedInfo.CanonicalizationMethodObject;
//canonicalizationMethodObject.Resolver = xmlResolver;
//canonicalizationMethodObject.BaseURI = securityUrl;
SetPrefix(prefix, document.DocumentElement); //мы устанавливаем префикс перед вычислением хеша (иначе подпись не будет действительной)
canonicalizationMethodObject.LoadInput(document);
canonicalizationMethodObject.GetDigestedOutput(hash);
}
private static void SetPrefix(string prefix, XmlNode node)
{
foreach (XmlNode n in node.ChildNodes)
SetPrefix(prefix, n);
node.Prefix = prefix;
}
}
`
Здравствуйте!
Имеется сертификат и закрытый ключ к нему. Как расшифровать строку, зашифрованную этим сертификатом? Ассиметричное шифрование подразумевает, что шифруется открытым ключом, а расшифровывается закрытым. Пробовал делать разными способами с помощью Вашей библиотеки, но результат один и тот же - ошибка
ASN.1 encoded byte array contains invalid structure 'Gost_R3410_KeyTransport'
Один из способов:
public static byte[] DecryptKey(string encDataInbase64, X509Certificate2 cert)
{
Gost_R3410_2012_256_AsymmetricAlgorithm assymAlgorithm = cert.GetPrivateKeyAlgorithm() as
Gost_R3410_2012_256_AsymmetricAlgorithm;
SymmetricAlgorithm sessionKey = GostEncryptedXml.DecryptKey(Convert.FromBase64String(encDataInbase64), assymAlgorithm);
return sessionKey.Key;
}
Пожалуйста, подскажите, что я делаю не так?
PS: расшифровка нужна на этапе 2 аутентификации по руководству https://docs-ke.readthedocs.io/ru/latest/auth/%D0%BF%D0%BE%20%D1%81%D0%B5%D1%80%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D1%83.html
Ситуация следующая: на одном сервере установлены КриптоПРО 4 и VipNet. При шифровании по ГОСТ 34.10 - 2012 (ЭЛН и ФСС :)) выдавалось сообщение "Плохой ключ" при попытке шифрования сессионного ключа.
Даже при использовании в коде
using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm(ProviderType.CryptoPro_2012_512))
Сама ошибка:
System.Security.Cryptography.CryptographicException: Плохой ключ.
в GostCryptography.Native.CryptoApiHelper.ExportCspBlob(SafeKeyHandleImpl symKeyHandle, SafeKeyHandleImpl keyExchangeHandle, Int32 blobType)
в GostCryptography.Gost_R3410.Gost_R3410_KeyExchangeAlgorithm.EncodeKeyExchangeInternal(Gost_28147_89_SymmetricAlgorithm keyExchangeAlgorithm, Int32 keyExchangeExportAlgId)
в GostCryptography.Gost_R3410.Gost_R3410_KeyExchangeAlgorithm.EncodeKeyExchangeInternal(Gost_28147_89_SymmetricAlgorithm keyExchangeAlgorithm, GostKeyExchangeExportMethod keyExchangeExportMethod)
в GostCryptography.Gost_R3410.Gost_R3410_KeyExchangeAlgorithm.EncodeKeyExchange(SymmetricAlgorithm keyExchangeAlgorithm, GostKeyExchangeExportMethod keyExchangeExportMethod)
в GostCryptography.Gost_R3410.Gost_R3410_KeyExchangeFormatter`3.CreateKeyExchangeInfo(SymmetricAlgorithm keyExchangeAlgorithm)
в GostCryptography.Gost_R3410.Gost_R3410_KeyExchangeFormatter`3.CreateKeyExchangeData(SymmetricAlgorithm keyExchangeAlgorithm)
в GostCryptography.Xml.GostEncryptedXmlImpl.EncryptKey(Gost_28147_89_SymmetricAlgorithmBase sessionKey, GostAsymmetricAlgorithm publicKey)
в GostCryptography.Xml.GostEncryptedXml.EncryptKey(Gost_28147_89_SymmetricAlgorithmBase sessionKey, GostAsymmetricAlgorithm publicKey)
Для себя решил проблему, изменив в Native\CryptoAPIHelper.cs в методе public static ProviderType GetAvailableProviderType_2012_512()
Сначала проверку на установленный криптопро, затем на випнет.
Собственно вопрос: а как можно в новой версии установить предпочитаемый тип криптопровайдера? В классе GostCryptoConfig они все readonly.
Александр, добрый день.
Пытаюсь использовать вашу библиотеку в следующей задаче:
PDF файл зашифровать через CryptoPro и сохранить полученный результат в БД.
Если использую код из примера:
var sharedKey = new Gost28147SymmetricAlgorithm();
var dataStream = new MemoryStream(Encoding.UTF8.GetBytes("Some data for encrypt..."));;
var encryptedDataStream = EncryptDataStream(sharedKey, dataStream);
var decryptedDataStream = DecryptDataStream(sharedKey, encryptedDataStream);
то dataStream совпадает с decryptedDataStream;
но если в dataStream кладу содержимое файла PDF,
dataStream = new MemoryStream(Convert.FromBase64String(obj.Content));
то дешифрованный результат не совпадает с исходным.
@AlexMAS, здравствуйте!
Нужно подписать сообщение по ГОСТу на стороне сервера в веб-приложении, которое хостится в IIS. Токен воткнут в сервер, личный сертификат установлен в хранилище личных сертификатов компьютера. При вызове метода SetSigningCertificate возникает NullReferenceException. Не подскажете, с чем может быть связана проблема и как ее решить?
{"Message":"An error has occurred.","ExceptionMessage":"Ссылка на объект не указывает на экземпляр объекта.","ExceptionType":"System.NullReferenceException","StackTrace":" в System.Security.Cryptography.X509Certificates.X509CertificateHelper.GetPrivateKeyAlgorithm(X509Certificate2 certificate)\r\n в GostCryptography.Xml.GostSignedXml.SetSigningCertificate(X509Certificate2 certificate)\r\n
Upd: при импорте с закрытым ключом проблема не наблюдается
Upd2: Включение взаимодействия с рабочим столом проблему не решило
Происходи ошибка:
System.Security.Cryptography.CryptographicException: Error occurred during a cryptographic operation.
в CryptoApiHelper.SignValue(SafeProvHandleImpl providerHandle, SafeHashHandleImpl hashHandle, Int32 keyNumber, Byte[] hashValue)
Конкретно при вычислении размера подписи, в этом кусочке:
if (!CryptoApi.CryptSignHash(hashHandle, (uint)keyNumber, null, 0, null, ref signatureLength))
{
throw CreateWin32Error();
}
Часто повторяется, в чем может быть проблема?
Хотим переехать на новую платформу, а не можем из-за отсутствия GostCryptography...
Очень прошу рассмотреть возможность портировать библиотеку под Net 5. или .Net Core
Здравствуйте.
Для метода Sign реализовали кастомную трансорфмацию:
<ds:Transform Algorithm="urn://smev-gov-ru/xmldsig/transform" />
И все работает хорошо...
Но когда пытаемся реализовать метод Verify, то ловим исключение
Код (взят из тестов)
GostSignedXml signedXml = new GostSignedXml(signedSmevRequest) {GetIdElementHandler = GetSmevIdElement};
XmlNodeList nodeList = signedSmevRequest.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl);
XmlNode node = nodeList[0];
XmlElement el = node as XmlElement;
//крашится на этом моменте
signedXml.LoadXml(el);
Исключение
System.Security.Cryptography.CryptographicException: Обнаружено неизвестное преобразование.
в System.Security.Cryptography.Xml.Reference.LoadXml(XmlElement value)
в System.Security.Cryptography.Xml.SignedInfo.LoadXml(XmlElement value)
в System.Security.Cryptography.Xml.Signature.LoadXml(XmlElement value)
в System.Security.Cryptography.Xml.SignedXml.LoadXml(XmlElement value)
в GostCryptography.Xml.GostSignedXml.LoadXml(XmlElement element)
XML файл на выходе с метода Sign имеет следующую структуру
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:SendRequestResponse xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.2" xmlns:ns2="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.2" xmlns:ns3="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/faults/1.2">
<ns2:MessageMetadata Id="SIGNED">
<ns2:MessageId></ns2:MessageId>
<ns2:MessageType></ns2:MessageType>
<ns2:Sender>
<ns2:Mnemonic></ns2:Mnemonic>
</ns2:Sender>
<ns2:SendingTimestamp></ns2:SendingTimestamp>
<ns2:Recipient>
<ns2:Mnemonic></ns2:Mnemonic>
</ns2:Recipient>
<ns2:Status></ns2:Status>
</ns2:MessageMetadata>
<ns2:SMEVSignature>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411" />
<ds:Reference URI="#SIGNED">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:Transform Algorithm="urn://smev-gov-ru/xmldsig/transform" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411" />
<ds:DigestValue></ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue></ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate></ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
</ns2:SMEVSignature>
</ns2:SendRequestResponse>
</soap:Body>
</soap:Envelope>
Опытным путем было выяснено, что ошибка появляется только если есть
<ds:Transform Algorithm="urn://smev-gov-ru/xmldsig/transform" />
Как решить данную проблему с кастомной трансофрмацией?
Здравствуйте, в общем пытаюсь пользоваться библиотекой для проверки оригинала файла и подписи. Делаю как то так:
public void CheckSignature()
{string sgnPath = "D:/test/5d3ef84a-8328-44de-b97a-e5d6ce82e1b9.docx.sgn"; string docxPath = "D:/test/5d3ef84a-8328-44de-b97a-e5d6ce82e1b9.docx"; byte[] sgnBuffer = new byte[0];> using (var sgnStream = new FileStream(sgnPath, FileMode.Open)) { sgnBuffer = new byte[(int)sgnStream.Length]; sgnStream.Read(sgnBuffer, 0, (int)sgnStream.Length); GostSignedCms cms = new GostSignedCms(); cms.Decode(sgnBuffer); var certificate = cms.Certificates[0]; var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm(); using (var docxStream = new FileStream(docxPath, FileMode.Open)) { var res = VerifySignature(publicKey, docxStream, sgnBuffer); Console.WriteLine(res); Console.Read(); } } } private static bool VerifySignature(AsymmetricAlgorithm publicKey, Stream dataStream, byte[] signature) { var signatureDescription = (SignatureDescription)GostCryptoConfig.CreateFromName(publicKey.SignatureAlgorithm); byte[] hash; using (var hashAlg = signatureDescription.CreateDigest()) { hash = hashAlg.ComputeHash(dataStream); } var deformatter = signatureDescription.CreateDeformatter(publicKey); deformatter.SetHashAlgorithm(signatureDescription.DigestAlgorithm); return deformatter.VerifySignature(hash, signature); }
По моим доводам вроде как все верно, но deformatter.VerifySignature(hash, signature) дает отрицательный результат. Вот тут https://crypto.kontur.ru/verify проверял файл и подпись все нормально. Подскажите пожалуйста что я делаю не так?
Делаю верификацию ЭП — отсоединенную, в формате PKCS#7 по значению хэш-функции
Есть сигнатура отсоединенной подписи и сообщение которую хочу проверить.
При проверке на сайте госуслуг проверка проходит успешно.
Код взял из примера
byte[] signature_byte = System.Convert.FromBase64String("MIIcrwYJKoZIhvcNAQc....");
byte[] message = Encoding.UTF8.GetBytes("Hello world");
var signedCms = new GostSignedCms(new ContentInfo(message), true);
signedCms.Decode(signature_byte);
try
{
// Проверка подписи CMS/PKCS#7
signedCms.CheckSignature(true);
}
catch (Exception exc)
{
}
При выполнении кода вылетает ошибка с текстом: {"Unknown algorithm '1.2.643.7.1.1.1.1'."}
Тестил на компьютерах: С установленной VipNet CSP (4.2.11.58753) и КриптоПро CSP (4.0.9944), так же откомпилированную версию на компьютере только с КриптоПро CSP версии 4.0.9963 (Установлен КриптоПро.NET Сервер версия 1.0.7775.0, КриптоПро.NET SDK версия 1.0.7775.0)
Выходит аналогичная ошибка.
Подскажите в чем может быть проблема?
возможно причина в платформе, но именно такая конфигурация довольно часто имеется у клиентов: winserver2008r2 + crypto-pro5.0.11319.
сертификат с гост2012-256.
при указании сертификата для подписания получаю ошибку:
Exception: System.NullReferenceException: Object reference not set to an instance of an object.
at GostCryptography.Gost_R3410.Gost_R3410_AsymmetricAlgorithm`2..ctor(CspParameters providerParameters, Int32 keySize)
at System.Security.Cryptography.X509Certificates.X509CertificateHelper.GetPrivateKeyAlgorithm(X509Certificate2 certificate)
at GostCryptography.Xml.GostSignedXml.SetSigningCertificate(X509Certificate2 certificate)
Здравствуйте! Возможны ли утечки памяти при использовании библиотеки GostCryptography? Обращался ли к Вам кто-либо с данной проблемой? В коде своих сервисов все объекты после использования мы освобождаем. Мы используем GostCryptography для шифрования и подписи сообщений. Взаимодействие с сервисом ФСС для отправки ЭЛН(шифрование) и взаимодействие с Федеральной электронной регистратурой (подпись запросов). На сервере в продуктивном контуре, где запущены наши сервисы, стоит крипто-про CSP 4.0.9963, Версия ядра СКЗИ: 4.0.9014 KC1. ОС: Windows Server 2016 Standart, наблюдается постоянное увеличение памяти, используемое сервисами. Может подскажите куда копать?
Здравствуйте, как просмотреть ключи в контейнере , используя GostCryptography. Криптопровайдер VipNet
Здравствуйте. Использую библиотеку для подписи XML документов в формате сообщений PKCS #7.
И всё прекрасно работало, пока в качестве криптотокена использовалась джакарта. Но руководство купило ключи на рутокене и, как это обычно бывает, всё поломалось.
Исключение: «Неправильный открытый ключ поставщика.»
в System.Security.Cryptography.Pkcs.PkcsUtils.CreateSignerEncodeInfo(CmsSigner signer, Boolean silent)
Код:
ContentInfo content = new ContentInfo(message);
SignedCms signedCms = new SignedCms(content, false);
CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, certificate);
signer.IncludeOption = X509IncludeOption.EndCertOnly;
//signer.DigestAlgorithm = new Oid("1.2.643.2.2.9", "ГОСТ Р 34.11-94");
signedCms.ComputeSignature(signer);
return signedCms.Encode();
Исключение появляется в момент выполнения ComputeSignature(). Криптопровайдер VipNet.CSP.
Исправить проблему мне не удается. Возможно, Вы сможете мне подсказать, в какую сторону «думать». Спасибо.
Здравствуйте.
Есть ли возможность подписывать сообщение, а не HASH, чтобы сделать один файл с прикрепленной подписью?
Например для просмотра через КриптоАрм.
http://cpdn.cryptopro.ru/content/cades/plugin-samples-sign-detached.html
Вот что я имею в виду:
JavaScript
var oSignedData = cadesplugin.CreateObject("CAdESCOM.CadesSignedData");
oSignedData.Content = dataToSign; // тут передаются данные.
var sSignedMessage = oSignedData.SignCades(oSigner, CADESCOM_CADES_BES, detached=false); //это сообщение с прикрепленной подписью.
P.S.
На всякий случай, для проверки попробовал подписать данные в GostCryptography, и получил ошибку System.ArgumentOutOfRangeException: "Hash size must be 64 bytes.
Подумал а вдруг получится, но нет :)
private static byte[] CreateSignature1(GostAsymmetricAlgorithm privateKey, byte[] msgBytes)
{
return privateKey.CreateSignature(msgBytes);
}
Спасибо!
Добрый день!
При подписании XML и указания
SignedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"
возникает ошибка
System.Security.Cryptography.CryptographicException: SignatureDescription could not be created for the signature algorithm supplied
А при указании SignedXml.SignedInfo.SignatureMethod = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411"
ругается проверка СМЭВ:
The requested algorithm urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411 does not exist. Original Message was: null
Что я делаю не так?)
Ожидания СМЭВ:
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411" />
<ds:Reference URI="#PERSONAL_SIGNATURE">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411" />
<ds:DigestValue/>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue/>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate/>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
Реальность, которая у меня получилась:
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411" />
<Reference URI="#PERSONAL_SIGNATURE">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411" />
<DigestValue/>
</Reference>
</SignedInfo>
<SignatureValue/>
<KeyInfo>
<X509Data>
<X509Certificate/>
</X509Data>
</KeyInfo>
</Signature>
Использую GostCryptography, для создания открепленной (CMS Sign, PKCS7) подписи. Пользуюсь примером из тестового проекта "SignedCmsSignTest", идущего вместе с исходниками. Никак не получается программно указать пароль контейнера VipNet для создания автоматизации ЦП. Для обычного шифрования/подписи данных проблем не возникает, но в случае создания открепленной подписи, в классах GostSignedCms и NET CmsSigner нет возможности указать пароль контейнера приватного ключа или Алгоритм подписи с уже заданным ключом.
Даже когда использую конструктор public CmsSigner (CspParameters parameters) и в CspParameters, заполненным параметрами из сертификата добавляю SecureString с необходимым паролем и флагом подавления окна cspKeyParams.Flags = CspProviderFlags.NoPromp - все равно во время выполнения VipNet вываливает диалоговое окно с предложением ввести пароль контейнера.
var cspKeyParams = certificate.GetPrivateKeyInfo();
cspKeyParams.Flags = CspProviderFlags.NoPrompt;
cspKeyParams.KeyPassword = secStr;
var signer = new CmsSigner(cspKeyParams);
Судя по исходникам NET эти два параметра CspParameters просто игнорируются в недрах класса CmsSigner.
Можно ли добавить какую-либо возможность использовать в библиотеке пароль контейнера в данном случае?
P.S. Спасибо за библиотеку!
Current version lacks support for GOST 34.10-2012 (aka Streebog) signatures.
There are VipNet and CryptoPro implementations. But I have tested only VipNet. Rumors say that they are not compatible with each other. For me VipNet implementation is most important by now.
UPD: update algoritm info
(кстати, отвечать можно и на русском, если так удобнее)
И снова приветствую!
Не уверен, что это баг, но с виду выглядит, что так.
Последовал данному в другом вопросе совету и убрал передачу типа провайдера в конструкторы алгоритмов. Использую соответствующие свойства GostCryptoConfig
.
И тут вдруг выяснилось, что сломалось шифрование на сертификат ФСС, выпущенный по новым ГОСТам. Лечится это явной передачей CryptoPro_2012_512
в конструктор Gost_28147_89_SymmetricAlgorithm
. Решил посмотреть, что происходит по-умолчанию и дошёл вот до этого куска:
protected GostSymmetricAlgorithm() : this(GostCryptoConfig.ProviderType)
{
}
Но ведь если шифрование идёт на новый ГОСТ, то надо брать значение не из ProviderType
, а из ProviderType_2012_5121
или ProviderType_2012_1024
. Не знаю, можно ли с этим что-то сделать, но поведение странное.
Здравствуйте. При использовании сервиса СЕДО возникла проблема при отправке запроса getMessageRequest. А именно, что записывается в зашифрованном виде в элементах xml: DigestValue, SignatureValue?
I'm getting an exception while trying to sign some data
"Индекс за пределами диапазона. Индекс должен быть положительным числом, а его размер не должен превышать размер коллекции.
Имя параметра: index"
в System.Security.Cryptography.X509Certificates.X509ChainElementCollection.get_Item(Int32 index)
в System.Security.Cryptography.Pkcs.PkcsUtils.CreateBagOfCertificates(CmsSigner signer)
в System.Security.Cryptography.Pkcs.SignedCms.Sign(CmsSigner signer, Boolean silent)
в System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer, Boolean silent)
в GostCryptography.Pkcs.GostSignedCms.ComputeSignature(CmsSigner signer, Boolean silent)
в GostCryptography.Pkcs.GostSignedCms.ComputeSignature(CmsSigner signer)
Same code works on test machine, but fails on production, same certificate
Добрый день!
Попробовал воспользоваться Вашей библиотекой для подписи и проверки подписи потока байт с помощью сертификата и классов форматирования для ГОСТов 2012 года. Использовал код из примеров. При тестировании сложилась следующая картина:
Оба варианта csp последних версий. Это ошибка библиотеки или недоработки в VipNet Csp? По ГОСТам 2001 года все 4 теста отрабатывают без ошибок.
Добрый день, подскажите есть пример шифрования запроса на сервис ФСС под ГОСТ 2012
Александр, интересует вопрос относительно необходимости сертификации вашего ПО в госорганах.
Я правильно понимаю, что ваш .Net-провайдер использует исключительно интерфейс Microsoft CryptoAPI и через него обращается к крипто-провайдеру КриптоПро CSP или ViPNet CSP? Реализации самих алгоритмов шифрования в GostCryptography нет?
Таким образом, сертификация ФСТЭК не требуется? Или какие-то алгоритмы криптозащиты всё же есть в библиотеке?
Добрый день.
Пишу такой код
static void Main(string[] args)
{
X509Store x509CertificateStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
X509Certificate2Collection x509Certificate2Collection = null;
X509Certificate2 fssCertificate;
x509CertificateStore.Open(OpenFlags.ReadOnly);
x509Certificate2Collection = x509CertificateStore.Certificates.Find(X509FindType.FindBySerialNumber, "00c4750d5b11e4db80e811f4cab74fa01e", false);
if (x509Certificate2Collection.Count == 1)
{
fssCertificate = new X509Certificate2(x509Certificate2Collection[0]);
}
else
{
fssCertificate = null;
}
try
{
using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm(ProviderType.CryptoPro_2012_512))
{
var publicKey = (GostAsymmetricAlgorithm)fssCertificate.GetPublicKeyAlgorithm();
byte[] encryptedKey = GostEncryptedXml.EncryptKey(sessionKey, publicKey);
}
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
Получаю ошибку System.Security.Cryptography.CryptographicException: "Плохой ключ."
Сертификат беру отсюда
https://lk.fss.ru/FSS_PROD_CERT_2019_34.10-2012.cer
Использую алгоритм ГОСТ 34.10.2012
Крипртопровайдер крипто про CSP 4.0.9963
Подскажите, что я делаю неправильно.
Спасибо за помощь.
Доброго дня
А планируется ли поддержка ГОСТ 34.12-2018 (Магма и Кузнечик, бывшие ГОСТ Р 34.12-2015)
P.S. Спасибо за либу
здравствуйте, Александр! очень благодарен вам за такую библиотеку, особенно за примеры кода к ней!
мой проект - реализация взаимодействия с ФСС по ЭЛН со стороны медицинских организаций.
(https://cabinets-test.fss.ru/eln.html)
у меня появились трудности её применения при переходе на новый ГОСТ и новую версию вашей разработки.
Времени суток!
Столкнулся со странной бедой: приходят подписанные файлы, которые не хотят проверяться. При том, что с виду там проблем никаких быть не должно.
И всё бы ничего, но их отлично проверяет сервис от КриптоПро! Вот этот: https://www.justsign.me/verifycpca/Verify/
Подпись, сделанную GostCryptography, он, напротив, проверять не хочет.
Я в мат. части тут не очень силён, поэтому могу упускать что-то очень очевидное. Для проверки брал метод VerifyXmlDocumentSignature из тестов.
Заранее благодарен за помощь!
Добрый вечер!
Использую net8.0 и
<PackageReference Include="GostCryptography" Version="2.0.11" />
как применить Gost_R3411_2012_256... ?
на строке signer.CheckSignature(false); получаю ошибку Unknown algorithm '1.2.643.7.1.1.1.1'
Помогите пожалуйста
Здравствуйте, коллеги!
С 2017 года используем GostCryptography для взаимодействия с ФСС в части обмена данными ЭЛН. За библиотеку Автору отдельное спасибо. Все прекрасно работало, до появления сервиса версии 2.0.
С появлением нового сервиса, на запрос ЭЛН по № и СНИЛС (в тестовый контур https://docs-test.fss.ru/ws-insurer-crypto-v20/FileOperationsLnService), всегда возвращается ошибка: "ru.fss.integration.ws.fault.v01.InternalException: Не удалось расшифровать сообщение. Возможно сообщение зашифровано на ключе отличном от ключа уполномоченного лица ФСС. Проверьте правильность и актуальность ключа уполномоченного лица ФСС. class ru.ibs.cryptopro.jcp.eln.crypt.CryptoException".
В процессе отладки удалось выяснить, что тестовый контур ЭЛН 2.0 не принимает сертификат уполномоченного лица ФСС для тестового контура (https://cabinets-test.fss.ru/FSS_TEST_CERT_2021.cer), а только сертификат для рабочего контура (https://cabinets.fss.ru/FSS_PROD_CERT_2021.cer). Также тестовый контур 2.0 (в отличии от тестового контура 1.1) не принимает тестовые сертификаты (выданные тестовыми УЦ), а только выданные акредитованными УЦ (т.е. полноценные сертификаты).
При выполнении этих условий АРМ ФСС выполняет запрос ЭЛН по № и СНИЛС и ему сервис возвращает: "Ошибка: ORA-20001: Некорректные параметры: Рег. номер в запросе и ОГРН в сертификате ЭП. Не найден страхователь с такими параметрами, а также отсутствует уполномоченный представитель с таким сертификатом ЭП". Что, в общем корректно (если не обращать внимание, что контур тестовый), так как используется сертификат страхователя, который не участвует в обмене данными ЭЛН.
Запрос в тестовый контур ЭЛН 2.0 без шифрования данных (https://docs-test.fss.ru/ws-insurer-v20/FileOperationsLnService) выполняется и сервис возвращает: "ORA-20001: Номер 306735316028 принадлежит к ЛН на бумажном бланке". Что тоже выглядит корректно. То есть, на лицо проблема с шифрованием (или расшифровыванием на стороне ФСС) сообщения.
Код метода и текст сообщения, передаваемое сервису ФСС в следующих сообщениях.
Кто ни будь подскажите, в чем моя ошибка.
В Windows 10, 2012R2, 2016 не работают примеры для шифрования/расшифрования данных с передачей сессионного ключа. Например, EncryptDecryptSessionKeyTest
.
При попытке расшифровать сессионный ключ функция CryptoApi.CryptImportKey
выдает ошибку "Плохой ключ" (для VipNet) или "Плохие данные" (для КриптоПро).
Stacktrace:
в GostCryptography.Native.CryptoApiHelper.ImportCspBlob(Byte[] importedKeyBytes, SafeProvHandleImpl providerHandle, SafeKeyHandleImpl publicKeyHandle, SafeKeyHandleImpl& keyExchangeHandle) в \Source\GostCryptography\Native\CryptoApiHelper.cs:строка 905
в GostCryptography.Native.CryptoApiHelper.ImportKeyExchange(SafeProvHandleImpl providerHandle, GostKeyExchangeInfo keyExchangeInfo, SafeKeyHandleImpl keyExchangeHandle) в \Source\GostCryptography\Native\CryptoApiHelper.cs:строка 958
в GostCryptography.Cryptography.GostKeyExchangeAlgorithm.DecodeKeyExchangeInternal(Byte[] encodedKeyExchangeData, Int32 keyExchangeExportAlgId) в \Source\GostCryptography\Cryptography\GostKeyExchangeAlgorithm.cs:строка 150
Сессионный ключ как-то некорректно передается...
Т.е. не удается расшифровать зашифрованные данные на той же самой машине тем же самым процессом. Не удается также расшифровать эти данные и на других машинах, например, под Windows 7.
При этом в Windows 7 шифрование работает корректно на тех же самых сертификатах, данные шифруются корректно. Примеры успешно работают.
В чем может быть проблема?
SignedXmlTransformTest - не проходит.
В лог пишет:
System.Security.Cryptography.Xml.SignedXml Information: 17 : [GostSignedXmlImpl#02093e65, UnsafeTransformMethod] Метод преобразования "http://www.w3.org/TR/1999/REC-xslt-19991116" не находится в списке безопасных. Безопасные методы преобразования: "http://www.w3.org/TR/2001/REC-xml-c14n-20010315", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments", "http://www.w3.org/2001/10/xml-exc-c14n#", "http://www.w3.org/2001/10/xml-exc-c14n#WithComments", "http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/2000/09/xmldsig#base64", "urn:mpeg:mpeg21:2003:01-REL-R-NS:licenseTransform", "http://www.w3.org/2002/07/decrypt#XML".
System.Security.Cryptography.Xml.SignedXml Information: 12 : [GostSignedXmlImpl#02093e65, VerificationFailure] Проверка Ссылки не прошла.
Одно из решений - добавить в реестр
http://go.microsoft.com/fwlink/?linkid=747061&clcid=0x409
System.Security.Cryptography.CryptographicException : '1.2.643.7.1.1.2.2' is not a known hash algorithm.
Добрый день! Я не смог найти в примерах возможности расшифровки текста ассиметричным ключом. Как это можно сделать?
Приветствую, есть задача принудительно шифровать XML по ГОСТ 2001 года, подскажите, как это можно сделать и можно ли вообще...
КриптопроCSP установдлен
Сертификат корректный (но privateKey свойство у него недоступно почему-то), но при попытке подписать сообщение ниже приведенным кодом возникает ошибка:
GostCryptoConfig.ProviderType = GostCryptography.Base.ProviderType.CryptoPro_2012_512;
//Создание объекта для подписи сообщения
var signedCms = new GostSignedCms(new ContentInfo(message),true);
// Создание объект с информацией о подписчике
var signer = new CmsSigner(certificate);
var tt = certificate.GetHashAlgorithm();
//signer.DigestAlgorithm = Oid.FromOidValue("1.2.643.7.1.1.2.2", OidGroup.HashAlgorithm); //GostCryptography.Asn1.Gost.Gost_R3410_2012_256.Gost_R3410_2012_256_Constants.HashAlgorithm.ToOid();
// Включение информации только о конечном сертификате (только для теста)
signer.IncludeOption = X509IncludeOption.EndCertOnly;
// Создание подписи для сообщения CMS/PKCS#7
signedCms.ComputeSignature(signer);
Ошибка:
'1.2.643.7.1.1.2.2' is not a known hash algorithm.
trace:
at Internal.Cryptography.PkcsHelpers.GetDigestAlgorithm(String oidValue, Boolean forVerification)
at System.Security.Cryptography.Pkcs.CmsSigner.Sign(ReadOnlyMemory`1 data, String contentTypeOid, Boolean silent, X509Certificate2Collection& chainCerts)
at System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer, Boolean silent)
at GostCryptography.Pkcs.GostSignedCms.ComputeSignature(CmsSigner signer, Boolean silent)
at GostCryptography.Pkcs.GostSignedCms.ComputeSignature(CmsSigner signer)
Что я делаю неверно?
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm(); - когда я попытался взять public key возваращает ошибку {"Алгоритм ключа сертификата не поддерживается."}
В моем ключе
Publickey.Oid: {
Value: "1.2.398.3.10.1.1.1.1"
FriendlyName: "ГОСТ 34.310-2004."
}
Можете помочь, и подсказать, у вас получается не реализован верификация подписи этого алгоритма?
В новую версию VipNet 4.4.2 добавили "Совместимость с продуктами КриптоПро"
Эта штука ставится юзеру по умолчанию. Что происходит в реестре:
Соответственно, проверки что за криптопровайдер по его типу (75, 80, 81) перестанут работать, т.к. VipNet мимикрирует под CryptoPro, например https://github.com/AlexMAS/GostCryptography/blob/master/Source/GostCryptography/Base/ProviderType.cs - становится немного не актуален, если нужно действительно отделять випнет от криптопро
В официальной документации толком информации про это нет, есть только один абзац, что это сделано якобы для совместимости с плагином криптопро для браузера
Добрый день. Для работы требуется установленное КриптоПРО CSP на ПК, или вся информация об OID и ключах шифрования тут имеется?
Пытаюсь декодировать зашифрованный файл с подписью:
GostSignedCms gostSignedCms = new GostSignedCms();
gostSignedCms.Decode(fileName);
Получаю ошибку: "System.Security.Cryptography.CryptographicException: Недопустимый тип криптографического сообщения."
С установленным криптопро csp и стандартным классом .net EnvelopedCms все удается сделать. Но имеется необходимость сделать реализацию без установленного криптопро, чтобы можно было опубликовать приложение в вэб, без установленного криптопро, в котором имеется вся информация по алгоритмам шифрования: https://cpdn.cryptopro.ru/content/csp40/html/group___pro_c_s_p_ex_DP8.html
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.