03.10.2007 16:51:48Замена CryptAcquireCertificatePrivateKey Ответов: 2
jar
Исходная задача:
Нужно вместо 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? В чём здесь ошибка?..
 
Ответы:
03.10.2007 17:01:10Kirill Sobolev
А dwKeySpec Вы как задаете? CryptAcquireCertificatePrivateKey ее просто возвращает.
03.10.2007 17:12:43jar
Точно!
В этом и была проблема. Спасибо!