Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.222.179.186] |
|
Сообщ.
#1
,
|
|
|
Добрый день. Давненько меня здесь не было. Вот понадобился совет экспертов.
Задача: Реализовать библиотеку для создания открепленной ЭЦП средствами cryptoAPI. Полученная подпись должна проходить проверку на госуслугах. Проблема: подпись я получаю, но проверку на госуслугах пройти не могу. Проблема лежит где-то на поверхности. Ниже код и скриншот с результатами проверки. bool sign_message( IN const std::string& message, IN const std::string& cert_store_name, IN const std::string& signer, OUT std::string& signature, OUT std::string& error_message) { signature = ""; error_message = ""; const auto message_length = static_cast<DWORD>(message.length() + 1); // Открываем хранилище сертификатов HCERTSTORE store_handle; if (!(store_handle = CertOpenStore( CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, string2wide_string(cert_store_name).c_str()))) { error_message = get_error_message(ERR_OPEN_STORE); return false; } // Получаем указатель на наш сертификат PCCERT_CONTEXT pSigner_cert = CertFindCertificateInStore( store_handle, MY_TYPE, 0, CERT_FIND_SUBJECT_STR, string2wide_string(signer).c_str(), NULL); if(!pSigner_cert) { error_message = get_error_message(ERR_CERT_NOT_FOUND); return false; } // Переменные для данных и длины подписи BYTE *pSigned_message_blob; DWORD signed_message_blob_length; // Создаем и заполняем структуру для создания ц.п. CRYPT_SIGN_MESSAGE_PARA signature_params; signature_params.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA); signature_params.dwMsgEncodingType = PKCS_7_ASN_ENCODING; signature_params.pSigningCert = pSigner_cert; signature_params.HashAlgorithm.pszObjId = signature_params.pSigningCert->pCertInfo->SignatureAlgorithm.pszObjId; signature_params.HashAlgorithm.Parameters.cbData = NULL; signature_params.cMsgCert = 1; signature_params.rgpMsgCert = &pSigner_cert; signature_params.cAuthAttr = 0; signature_params.dwInnerContentType = 0; signature_params.cMsgCrl = 0; signature_params.cUnauthAttr = 0; signature_params.dwFlags = 0; signature_params.pvHashAuxInfo = nullptr; signature_params.rgAuthAttr = nullptr; BYTE* pbMessage = (BYTE*)message.c_str(); const BYTE* message_array[] = { pbMessage }; DWORD message_size_array[1]; message_size_array[0] = message_length; try { PCCERT_CONTEXT pCertContext = NULL; // Получаем длину буфера подписи if (!CryptSignMessage( &signature_params, // указатель на SigParams TRUE, // подпись создается отдельно 1, // число сообщений message_array, // сообщение message_size_array, // длина сообщения NULL, // буфер для подписи &signed_message_blob_length)) // размер буфера { error_message = get_error_message(ERR_CRYPT_SIGN_MESSAGE); return false; } } catch (...) { } // выделяем память под подпись if (!(pSigned_message_blob = new BYTE[signed_message_blob_length])) { error_message = get_error_message(ERR_SIGN_BAD_ALLOC); return false; } // формируем подпись if (!CryptSignMessage( &signature_params, // указатель на параметры подписи TRUE, // подпись создается отдельно 1, // число сообщений message_array, // сообщение message_size_array, // длина сообщения pSigned_message_blob, // буфер для подписи &signed_message_blob_length)) // размер буфера { error_message = get_error_message(ERR_CREATE_SIGNATURE); return false; } // переводим в base64 формат signature = base64_encode(pSigned_message_blob, signed_message_blob_length); write_file("signature.sign", signature.c_str(), signature.length()); if (pSigned_message_blob) delete pSigned_message_blob; if (pSigner_cert) CertFreeCertificateContext(pSigner_cert); if (!CertCloseStore(store_handle, CERT_CLOSE_STORE_CHECK_FLAG)) { error_message = get_error_message(ERR_CLOSE_STORE); return false; } error_message = get_error_message(SUCCESS); return true; }// sign_message Прикреплённая картинка
|
Сообщ.
#2
,
|
|
|
Дело было не в бобине. Вопрос закрыт. Код вполне себе корректный, хотя и не совсем чистый.
|