| ||||
| ||||
Исходная задача: Нужно вместо CryptAcquireCertificatePrivateKey действовать напрямую через CryptAcquireContext, т.к. нужно убрать окна КриптоПро: если токен не вставлен, программа выведет окошко с этой надписью и будет ждать действий от пользователя, что в нашем случае недопустимо. Я из структуры PCCERT_CONTEXT узнаю тип, имя криптопровайдера и имя контейнера. Далее тестовый код: BOOL bRet = CryptAcquireContext(&hProv, _T("\\\\.\\AKS ifdh 0\\SCARD\\ETOKEN_PRO32_42576014\\CC01\\4CD1"), _T("Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider"), 75, 0); if (!bRet) { //Error } // Вместо вышеописанного было и работало вот это: // if(!CryptAcquireCertificatePrivateKey(*this, 0, NULL, &hProv, &dwKeySpec, &bFree)) {/*Error*/} CMSG_SIGNER_ENCODE_INFO signerInfo = {0}; signerInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO); signerInfo.pCertInfo = PCCERT_CONTEXT(*this)->pCertInfo; signerInfo.hCryptProv = hProv; signerInfo.dwKeySpec = dwKeySpec; signerInfo.HashAlgorithm.pszObjId = (LPSTR)(this->GetHashOID().data()); signerInfo.pvHashAuxInfo = NULL; std::vector<CMSG_SIGNER_ENCODE_INFO> vecSignerInfos; vecSignerInfos.push_back(signerInfo); CMSG_SIGNED_ENCODE_INFO info = {0}; info.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO); info.cSigners = static_cast<DWORD>(vecSignerInfos.size()); info.rgSigners = &vecSignerInfos[0]; HCRYPTMSG hMsg; hMsg = CryptMsgOpenToEncode(MY_ENCODING_TYPE, 0, CMSG_SIGNED, &info, 0, NULL); if (!hMsg) { //Error } if(!CryptMsgUpdate(hMsg, &vecInData[0], static_cast<DWORD>(vecInData.size()), TRUE)) { DWORD dwRes = GetLastError(); } В результате, после CryptMsgUpdate получаем ошибку NTE_BAD_KEYSET. (Для простоты привёл кусок кода без программного задания пин-кода и CRYPT_SILENT) Вопрос: как правильно заменить функцию CryptAcquireCertificatePrivateKey? В чём здесь ошибка?.. | ||||
Ответы: | ||||
| ||||
А dwKeySpec Вы как задаете? CryptAcquireCertificatePrivateKey ее просто возвращает. | ||||
| ||||
Точно! В этом и была проблема. Спасибо! | ||||