Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline EgorOkhotin  
#1 Оставлено : 28 июня 2019 г. 8:48:16(UTC)
EgorOkhotin

Статус: Активный участник

Группы: Участники
Зарегистрирован: 13.06.2019(UTC)
Сообщений: 30
Российская Федерация
Откуда: Самара

Сказал(а) «Спасибо»: 4 раз
Выбрал сертификат из хранилища, распарсил название контейнера если есть, выбрал все алгоритмы, что поддерживает CSP. Теперь хочу импортировать ключ в CSP для проверки подписи,
но когда закидываю его, то у меня ошибка.

Ключ длиной 66 байт получается
Алгоритм ГОСТ 34.10 - 2012 512
Контекст открываю с флагом CRYPT_VERIFYCONTEXT
Платформа Windows 10 / Cent Os 7
Пишу под .NET через P/Invoke

При открытии контекста указваю только тип провайдера, а имя контейнера равно null, имя провайдера пробовал указывать и без него.

Возможно стандартные средства парсинга X509 не совсем корректно работает. Может кто подсказать?


Код:

if (!CryptoApi.CryptAcquireContext(
    ref provider, null, Constants.CP_GR3410_2012_STRONG_PROV_A, (uint)parametrs.ProviderType, Constants.CRYPT_VERIFYCONTEXT)) //parametrs is CspParametrs
{
    throw new SystemException();
}
                    
                
var publicKey = Certificate.GetPublicKey(); //X509Certificate2
if(!CryptoApi.CryptImportKey(provider, publicKey, (uint)publicKey.Length, invalid, 0U, ref keyHandle))
{
    var errCode = Marshal.GetLastWin32Error();
}

Отредактировано пользователем 28 июня 2019 г. 9:42:34(UTC)  | Причина: Не указана

Offline two_oceans  
#2 Оставлено : 28 июня 2019 г. 13:56:28(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 1,602
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 110 раз
Поблагодарили: 393 раз в 366 постах
Окрытие контекста правильное, а вот ключ какой-то странный, 66 байт не должно быть. Обычный размер ключа 64 байта, в начале видимо есть байты 04 40 - это обертка над ключом. Однако, 2 байтов обертки недостаточно для универсальной CryptImportKey, там обертка должна быть посерьезней чтобы отличить открытый ключ от закрытого. Тут есть 2 пути - 1) накидать нужную обертку в своей программе, благо она будет одинаковая для всех открытых ключей одного алгоритма; 2) использовать функцию именно для открытых ключей. У меня выглядит примерно так, но на другом языке программирования.
Код:
function GetPubKeyFromCertContext_(pCertCont:PCERT_CONTEXT;hProv:HCRYPTPROV;var hPubKey:HCRYPTKEY):cardinal;
var pKeyBlob:pcert_public_key_info;res:cardinal;
begin
  SetLastError(0);
  if pCertCont<>nil then begin
    // CryptImportPublicKeyInfo(hProv,MY_TYPE,&(pSignerCert->pCertInfo->SubjectPublicKeyInfo),&hPubKey))
    pKeyBlob:=@(pCertCont^.pCertInfo^.SubjectPublicKeyInfo);
    if not CryptCheck(CryptImportPublicKeyInfo(hProv,X509_ASN_ENCODING or PKCS_7_ASN_ENCODING,pKeyBlob, hPubKey),'CryptImportPublicKeyInfo') then res:=err_import_key else res:=0;
    SetLastError(0);
  end else res:=6;
  GetPubKeyFromCertContext_:=res;
end;

Отредактировано пользователем 28 июня 2019 г. 13:58:17(UTC)  | Причина: Не указана

Offline EgorOkhotin  
#3 Оставлено : 28 июня 2019 г. 14:20:14(UTC)
EgorOkhotin

Статус: Активный участник

Группы: Участники
Зарегистрирован: 13.06.2019(UTC)
Сообщений: 30
Российская Федерация
Откуда: Самара

Сказал(а) «Спасибо»: 4 раз
Автор: two_oceans Перейти к цитате
Окрытие контекста правильное, а вот ключ какой-то странный, 66 байт не должно быть. Обычный размер ключа 64 байта, в начале видимо есть байты 04 40 - это обертка над ключом. Однако, 2 байтов обертки недостаточно для универсальной CryptImportKey, там обертка должна быть посерьезней чтобы отличить открытый ключ от закрытого. Тут есть 2 пути - 1) накидать нужную обертку в своей программе, благо она будет одинаковая для всех открытых ключей одного алгоритма; 2) использовать функцию именно для открытых ключей. У меня выглядит примерно так, но на другом языке программирования.
Код:
function GetPubKeyFromCertContext_(pCertCont:PCERT_CONTEXT;hProv:HCRYPTPROV;var hPubKey:HCRYPTKEY):cardinal;
var pKeyBlob:pcert_public_key_info;res:cardinal;
begin
  SetLastError(0);
  if pCertCont<>nil then begin
    // CryptImportPublicKeyInfo(hProv,MY_TYPE,&(pSignerCert->pCertInfo->SubjectPublicKeyInfo),&hPubKey))
    pKeyBlob:=@(pCertCont^.pCertInfo^.SubjectPublicKeyInfo);
    if not CryptCheck(CryptImportPublicKeyInfo(hProv,X509_ASN_ENCODING or PKCS_7_ASN_ENCODING,pKeyBlob, hPubKey),'CryptImportPublicKeyInfo') then res:=err_import_key else res:=0;
    SetLastError(0);
  end else res:=6;
  GetPubKeyFromCertContext_:=res;
end;



Спасибо, действительно в начале ключа 0440. Не подскажете где можно про обертку ключа прочитать, так как этот ключ я кидал в непосредственно в csp?
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.