CryptoPro / libcore

44 stars 0 forks source link

Не удается получить доступ к закрытому ключу в веб-приложении #11

Closed Bykiev closed 1 year ago

Bykiev commented 1 year ago

Здравствуйте, возможно ли использование сервера kestrel для работы с ЭП? При использовании возникает ошибка: Object contains only the public half of a key pair. A private key must also be provided

Судя по всему, он не может получить доступ к закрытому ключу. Возможно, это можно как-то настроить или нужно обязательно проксировать Kestrel IIS/Nginx?

Захостил приложение на IIS, ошибка аналогичная, ключ установлен в личное хранилище пользователя, пул запущен от имени этого же пользователя...

Ошибка возникает при вычислении подписи (ComputeSignature)

Fasjeit commented 1 year ago

Добрый день, как именно вы получаете сертификат\ключ?

Bykiev commented 1 year ago

Поиск по отпечатку, сертификат находится. Токен с закрытым ключом вставлен в ПК

Fasjeit commented 1 year ago

Для объекта сертификата что возвращают свойства HasPrivateKey и PrivateKey?

Fasjeit commented 1 year ago

И сразу же проверить, что была произведена привязка сертификата из хранилища к ключу (в оснастке WIndowxs для сертификата отображается, что "Есть закрытый ключ для этого сертификата"

Bykiev commented 1 year ago

HasPrivateKey = true PrivateKey содержит информацию о закрытом ключе privateKeyInfo

Bykiev commented 1 year ago

И сразу же проверить, что была произведена привязка сертификата из хранилища к ключу (в оснастке WIndowxs для сертификата отображается, что "Есть закрытый ключ для этого сертификата"

Да, сообщение есть

Bykiev commented 1 year ago

Я ведь правильно задаю алгоритм хэширования string digestMethod = CpSignedXml.XmlDsigGost3411_2012_256Url;? При использовании string digestMethod = certificate.PrivateKey.KeyExchangeAlgorithm; возникает ошибка Could not create hash algorithm object.

Fasjeit commented 1 year ago

Есть ли пин-код на ключевой контейнер? Ошибка воспроизводится только в Kestrel (т.е. в приложении консольного типа ошибок нет)? Можете привести полный стек трейс ошибки?

Bykiev commented 1 year ago

Есть ли пин-код на ключевой контейнер? Ошибка воспроизводится только в Kestrel (т.е. в приложении консольного типа ошибок нет)? Можете привести полный стек трейс ошибки?

Консольное приложение не проверял, сейчас проверю. StackTrace:

в LibCore.Security.Cryptography.Gost3410_2012_256CryptoServiceProvider.SignHash(Byte[] rgbHash)
   в LibCore.Security.Cryptography.Gost3410_2012_256CryptoServiceProvider.SignHash(Byte[] rgbHash, HashAlgorithmName hashAlgName)
   в LibCore.Security.Cryptography.Gost2012_256SignatureFormatter.CreateSignature(Byte[] rgbHash)
   в System.Security.Cryptography.AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm hash)

Пин-код есть, но он запомнен

Bykiev commented 1 year ago

Точно такая же ошибка наблюдается и в консольном приложении

Bykiev commented 1 year ago

Может ли быть ошибка из-за того, что используется КриптоПро CSP 4.0.9963?

Fasjeit commented 1 year ago

У себя ошибку не воспроизводим, используя код из примера xml.

Поддерживается только csp 5.0 и только последний актуальный релиз, на момент написание этого сообщения это 5.0.12600. В более младших версиях не было нужных правок для корректной работы всех сценариев использования.

Bykiev commented 1 year ago

Обновил CSP до последней версии, ошибка по-прежнему наблюдается, пример моего кода (метод вызывается из примера):

var cert = CryptoHelper.FindByThumbprint(thumbprint, System.Security.Cryptography.X509Certificates.StoreName.My, System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser);
if(cert!= null)
{
    try
    {
        var sign = CryptoHelper.SignXmlFile(doc, cert.PublicKey.Key, cert);
        Console.WriteLine(sign.OuterXml);
    }
    catch(Exception ex) {
    }
Fasjeit commented 1 year ago

Подпись производится закрытым ключом, привязанным к сертификату.

Вы передаёте открытый ключ cert.PublicKey.Key и пытаетесь им подписать - на что и получаете ошибку, что объект не содержит закрытого ключа: SignXmlFile(doc, cert.PublicKey.Key, cert);

Получить закрытый ключ можно через свойство PrivateKey.

Bykiev commented 1 year ago

Спасибо, теперь работает!