Статус: Новичок
Группы: Участники
Зарегистрирован: 24.09.2020(UTC) Сообщений: 5
Сказал(а) «Спасибо»: 3 раз
|
Автор: two_oceans Добрый день. С "такой же" - это с какой? Автор темы тут наверно 5 или 6 разных ситуаций слепил в одну тему, про какую ошибку речь? Навскидку ни одна не похожа на Ваш вопрос.
Проблема в том что скрипт возвращает ошибку 0x8010002c Автор: two_oceans Где, собственно, вызовы: 1. CryptAcquireContext с именем контейнера и 2. CryptGetUserKey? Без них в hKey будет неизвестно что и запросить сертификат не выйдет. Вместо 1 еще может быть CryptAcquireCertificatePrivateKey, но тогда проще сертификат взять напрямую из PCERT_CONTEXT как поле pbCertEncoded структуры _CERT_CONTEXT, а длину сертификата из поля cbCertEncoded.
Далее. Что в переменной cd? По смыслу там должен быть hProv. Ключ точно AT_KEYEXCHANGE? Например, я воздерживаюсь от указания константы AT_KEYEXCHANGE в коде, так как контейнер может неожиданно оказаться с ключом AT_SIGNATURE (есть и другие значения dwKeySpec, например, для CNG или УЭК). Для госта таким ключом AT_SIGNATURE тоже можно пользоваться при обмене ключей, но доставляет проблемы когда ключ получателя и ключ отправителя не одинаковые - один AT_KEYEXCHANGE, другой AT_SIGNATURE.
Прошу прощения выложил какой-то кривой кусок.Никакой переменно cd нет, видимо попала сюда при переключения с консоли. Выкладываю надлежащий: Код:
...
// Получение дескриптора контейнера отправителя, находящегося в рамках провайдера.
if(!CryptAcquireContext( &hProv, argv[1], NULL, PROV_GOST_2012_256, 0)) HandleError("Error during CryptAcquireContext.");
#ifdef DEBUG_OUT
printf("02. The key container \"%s\" has been acquired. \n", argv[1]);
#endif
// Загрузка PUBLICKEYBLOB из сертификата, открытие файла, в котором содержится открытый ключ получателя.
if((fhCert = fopen(argv[2], "rb")))
{
#ifdef DEBUG_OUT
printf( "\tThe file '%s' was opened\n", argv[2]);
#endif
cbCert = (DWORD)fread(pbCert, 1, cbCert, fhCert);
if(!cbCert) HandleError( "Failed to read certificate\n" );
#ifdef DEBUG_OUT
printf( "\tCertificate was read from the '%s'\n", argv[2] );
#endif
pCertContext = CertCreateCertificateContext ( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, pbCert, cbCert);
if (!pCertContext) HandleError( "CertCreateCertificateContext" );
// Импортируем открытый ключ
if (!CryptImportPublicKeyInfoEx( hProv, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &(pCertContext->pCertInfo->SubjectPublicKeyInfo), 0, 0, NULL, &hPubKey))
{
CertFreeCertificateContext(pCertContext);
HandleError( "CryptImportPublicKeyInfoEx" );
}
#ifdef DEBUG_OUT
printf("\tPublic key imported from cert file\n");
#endif
CertFreeCertificateContext(pCertContext);
// экспорт открытого ключа получателя в BLOB
if (!CryptExportKey( hPubKey, 0, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen)) HandleError( "CryptExportKey" );
#ifdef DEBUG_OUT
printf("\tPublic key exported to blob\n");
#endif
}
// begin hack
// генерация эфемерной ключевой пары
if(!CryptGenKey(hProv, /* CALG_DH_EL_EPHEM */ CALG_DH_GR3410_12_256_EPHEM, CRYPT_EXPORTABLE, &hEphemeralKey)) HandleError("Error during CryptGenKey Ephemeral key.");
#ifdef DEBUG_OUT
printf("03. The Ephemeral key has been acquired. \n");
#endif
// экспорт открытого ключа отправителя в BLOB
if(!CryptExportKey(hEphemeralKey, 0, PUBLICKEYBLOB, 0, pbSenderPublicKeyBlob, &dwSenderPublicBlobLen)) HandleError("Error during CryptExportKey of Sender\'s public key.");
#ifdef DEBUG_OUT
printf("04. The Sender public key has been acquired. size of Blob = %d bytes\n", dwSenderPublicBlobLen);
#endif
// получаем значение открытого ключа отправителя из PUBLICKEYBLOB
memcpy(&pbKeyCipherValue[PUBKEY_OFFSET], &pbSenderPublicKeyBlob[dwSenderPublicBlobLen-PUBKEY_LEN], PUBKEY_LEN);
#ifdef DEBUG_OUT
if(!fwrite( pbSenderPublicKeyBlob, 1, dwSenderPublicBlobLen, fhSession_PublicKey)) HandleError( "The session key can not be written to the 'session_PublicKey.bin'\n" );
printf("\tThe session key was written to the 'session_PublicKey.bin'\n" );
#endif
// Получение дескриптора закрытого ключа отправителя. нам нужно для получения сертификата который вставим в запрос
if(!CryptGetUserKey( hProv, AT_KEYEXCHANGE, &hKey)) HandleError("Error during CryptGetUserKey private key.");
#ifdef DEBUG_OUT
printf("05. The private key has been acquired. \n");
#endif
// определяем размер блока памяти для получения нашего сертификата который мы пошлем в ФСС
if(!CryptGetKeyParam(hKey, KP_CERTIFICATE, NULL, &dwPubCertData, 0)) HandleError("Error during CryptGetKeyParam for determinating size of certificate.");
#ifdef DEBUG_OUT
printf("06. The size for Public Certificate has been acquired. \n");
#endif
Оишбка при вызове последнего метода. Что вы указываете вместо AT_KEYEXCHANGE ? Вообще ключ определяется как exchange. Код:
root@89ab132f3286:/opt/cprocsp/src/samples/CSP# csptest -keyset -check -cont 'test8'
CSP (Type:80) v5.0.10006 KC1 Release Ver:5.0.11944 OS:Linux CPU:AMD64 FastCode:READY:SSSE3,AVX.
AcquireContext: OK. HCRYPTPROV: 14719875
GetProvParam(PP_NAME): Crypto-Pro GOST R 34.10-2012 KC1 CSP
Container name: "test8"
Check header passed.
Signature key is not available.
Exchange key is available. HCRYPTKEY: 0xe62fd3
Symmetric key is not available.
UEC key is not available.
Check container passed.
Check sign passed.
Check verify signature on private key passed.
Check verify signature on public key passed.
Check import passed.
Keys in container:
exchange key
Extensions:
OID: 1.2.643.2.2.37.3.10
PrivKey: Not specified - 23.01.2022 10:58:48 (UTC)
Total: SYS: 0.020 sec USR: 0.030 sec UTC: 0.500 sec
[ErrorCode: 0x00000000]
Может быть проблема втом что опыты провожу на ключах сгенерированных на тестовом УЦ ? Отредактировано пользователем 11 ноября 2020 г. 13:25:55(UTC)
| Причина: Не указана
|