Аутентификация клиента Qt X.509 с использованием смарт-карты

Я пытаюсь получить доступ к защищенному сайту в c++ с помощью QNetworkAccessManager и основные запросы на отдых.
Сайт требует x.509 client certificate,
у меня есть smartcard который я хотел бы использовать для authenticate на этот сайт.

Я прочитал, что мне нужен закрытый ключ для аутентификации, который я затем могу установить для запроса в sslConfiguration() с помощью .setPrivateKey(), но смарт-карта не позволяет мне использовать закрытый ключ на смарт-карте.

Кто-нибудь знает, как Google Chrome, Internet Explorer или Microsoft Edge выполняют запросы на доступ к этим сайтам? Firefox, кажется, не работает со считывателем смарт-карт.

Я знаю, они используют CNG окон, но что я должен делать или иметь в виду, чтобы я мог использовать смарт-карту для аутентификации на этом сайте и использовать конечную точку REST.

Вот то, что я уже пытался получить закрытый ключ от смарт-карты и прикрепить его к запросу:

void MainWindow::getPrivateCert()
{
NCRYPT_PROV_HANDLE hProv;
if (NCryptOpenStorageProvider(&hProv, MS_SMART_CARD_KEY_STORAGE_PROVIDER, 0) != ERROR_SUCCESS) {
std::cout << "error 1" << std::endl;
return;
}

NCryptKeyName *keyName = new NCryptKeyName();
VOID *enumState = NULL;
int certCounter = 0;
while (NCryptEnumKeys(hProv, NULL, &keyName, &enumState, 0) == ERROR_SUCCESS) {
//std::wcout << keyName->pszName << std::endl;
NCRYPT_KEY_HANDLE keyHandle;
if (NCryptOpenKey(hProv, &keyHandle, keyName->pszName, keyName->dwLegacyKeySpec, 0) == ERROR_SUCCESS) {
BYTE *name = new BYTE[1024];
DWORD nameLen;
if (NCryptGetProperty(keyHandle, NCRYPT_NAME_PROPERTY, name, 1024, &nameLen, 0) == ERROR_SUCCESS) {
for (int i = 0; i < nameLen; i++) {
if (name[i] == 0) { continue; }
std::wcout << (wchar_t)name[i];
}
std::cout << std::endl;
std::cout << std::endl;
}
BYTE *size = new BYTE[1024];
DWORD sizeLen;
int certSize = 0;
if (NCryptGetProperty(keyHandle, NCRYPT_LENGTH_PROPERTY, size, 1024, &sizeLen, 0) == ERROR_SUCCESS) {
std::cout << "size: ";
for (int i = sizeLen; i >= 0; i--) {
std::wcout << (int)size[i];
int factor = pow(10, i);
certSize += (int)size[i] * factor;
}
std::cout << std::endl;
std::cout << std::endl;
}
printf("%d\n", certSize);
BYTE *cert = new BYTE[certSize*2];
DWORD certLen;
if (NCryptGetProperty(keyHandle, NCRYPT_CERTIFICATE_PROPERTY, cert, certSize*2, &certLen, 0) == ERROR_SUCCESS) {
printf("%d\n", certLen);
this->m_cert = new char[certLen];
this->m_certSize = certLen;
for (int i = 0; i < certLen; i++) {
//std::wcout << (char)cert[i];
this->m_cert[i] = cert[i];
}
std::cout << std::endl;
std::cout << std::endl;
}
NCryptFreeObject(keyHandle);
}
if(certCounter == this->certNumber) {
break;
}
certCounter++;
}
NCryptFreeBuffer(keyName);
}

getPrivateCert();
std::cout.write(this->m_cert, this->m_certSize) << std::endl;
QSslKey key(QByteArray(cert, certSize), QSsl::KeyAlgorithm::Rsa, QSsl::EncodingFormat::Der, QSsl::KeyType::PrivateKey, "");
QNetworkRequest request(QUrl(this->m_restEndpoint));
request.sslConfiguration().setPrivateKey(key);
request.setHeader(QNetworkRequest::KnownHeaders::UserAgentHeader, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
manager->get(request);

Я почти уверен, что мне не хватает некоторых очень важных шагов, но я не могу найти никакой полезной информации для аутентификации клиента c ++ x.509 с использованием смарт-карты.

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …