GostCryptography icon indicating copy to clipboard operation
GostCryptography copied to clipboard

Подпись сообщений в веб-приложении (IIS)

Open Bykiev opened this issue 5 years ago • 4 comments

@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: Включение взаимодействия с рабочим столом проблему не решило

Bykiev avatar Aug 10 '20 12:08 Bykiev

Здравствуйте. Складывается впечатление, что при вызове SetSigningCertificate() вы передаёте null вместо сертификата (возможно, нужно проверить логику поиска сертификата), либо сертификат без приватного ключа. Если вы хотите подписать сообщение публичным ключом, то попробуйте установить:

GostSignedXml.SigningKey = certificate.GetPublicKeyAlgorithm()

вместо вызова SetSigningCertificate().

AlexMAS avatar Aug 11 '20 03:08 AlexMAS

Спасибо, в метод SetSigningCertificate() точно передается сертификат, но приватный ключ находится на usb-токене. При использовании GostSignedXml.SigningKey = certificate.GetPublicKeyAlgorithm() при вычислении подписи (SignedXml.ComputeSignature()) возникает другая ошибка:

{"Message":"An error has occurred.","ExceptionMessage":"Object contains only the public half of a key pair. A private key must also be provided.","ExceptionType":"System.Security.Cryptography.CryptographicException","StackTrace":" в GostCryptography.Gost_R3410.Gost_R3410_AsymmetricAlgorithm2.SignHash(Byte[] hash)\r\n в GostCryptography.Gost_R3410.Gost_R3410_AsymmetricAlgorithm2.CreateSignature(Byte[] hash)\r\n в GostCryptography.Base.GostSignatureFormatter.CreateSignature(Byte[] hash)\r\n в System.Security.Cryptography.AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm hash)\r\n в System.Security.Cryptography.Xml.SignedXml.ComputeSignature()\r\n в CryptoPro.Sharpei.Xml.CPSignedXmlDetour.ComputeSignature()\r\

Upd: если закрытый ключ импортирован в хранилище реестр, то возникает ошибка "Поставщику не удалось выполнить действие, так как запрошено выполнение в автоматическом контексте.", если закрытый ключ импортирован в хранилище Диск, то документ подписывается

Bykiev avatar Aug 11 '20 06:08 Bykiev

Да, действительно, публичный ключ тут не подойдет. Вам нужно каким-то образом из USB-токена достать экземпляр приватного ключа и передать его в GostSignedXml.SigningKey. Как достать сертификат (приватный ключ) с USB-токена, подсказать не могу.

P.s. В вашем stack-trace фигурирует CryptoPro.Sharpei. Видимо, он установлен на вашей машине. Возможно, он будте конфликтовать с частью функциональности GostCryptography.

AlexMAS avatar Aug 11 '20 07:08 AlexMAS

Спасибо, буду изучать дальше!

Bykiev avatar Aug 11 '20 07:08 Bykiev

Проблема наблюдается только в случаях, когда сертификат установлен в хранилище компьютера. Для корректной работы нужно предоставить доступ к закрытому ключу, инструкция здесь: https://dss.cryptopro.ru/docs/adminguide/servicecertificates/privatekeyaccess.html

Bykiev avatar Sep 28 '22 14:09 Bykiev