| ||||
| ||||
Есть у кого-нибудь пример этой операции в CryptoAPI? Что то у меня этого никак не получается осуществить :\ Буду очень благодарен, ибо срочно нужно... | ||||
Ответы: | ||||
| ||||
extern "C" bool __declspec(dllexport) CosignMessage(const BYTE* signedMessage, DWORD signedMessageSize, BYTE* cosignedMessageBlob, DWORD* cosignedMessageBlobSize, LPCSTR certHash, DWORD certHashLength) { HCRYPTMSG cryptMsg; BYTE* pbCertHash; DWORD dwCertHashLength; HCERTSTORE hStoreHandle; PCCERT_CONTEXT certContext; CRYPT_HASH_BLOB blobCert; HCRYPTPROV hCryptProv = NULL; if (!CryptAcquireContext(&hCryptProv, NULL, NULL, CRYPT_PROV_TYPE, CRYPT_VERIFYCONTEXT)) { setLastError(); return false; } if (!CryptStringToBinaryA(certHash, certHashLength, CRYPT_STRING_HEX, NULL, &dwCertHashLength, 0, 0)) { CryptReleaseContext(hCryptProv, 0); setLastError(); return false; } pbCertHash = (BYTE*)malloc(dwCertHashLength); if (!pbCertHash) { CryptReleaseContext(hCryptProv, 0); setLastError(); return false; } if (!CryptStringToBinaryA(certHash, certHashLength, CRYPT_STRING_HEX, pbCertHash, &dwCertHashLength, 0, 0)) { CryptReleaseContext(hCryptProv, 0); free(pbCertHash); setLastError(); return false; } blobCert.cbData = dwCertHashLength; blobCert.pbData = pbCertHash; if (!(hStoreHandle = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, PERSONAL_STORE_NAME))) { CryptReleaseContext(hCryptProv, 0); free(pbCertHash); setLastError(); return false; } if(!(certContext = CertFindCertificateInStore(hStoreHandle, MY_ENCODING_TYPE, 0, CERT_FIND_HASH, &blobCert, NULL))) { CryptReleaseContext(hCryptProv, 0); CertCloseStore(hStoreHandle, 0); free(pbCertHash); setLastError(); return false; } if (!(cryptMsg = CryptMsgOpenToDecode(MY_ENCODING_TYPE, 0, 0, NULL, NULL, NULL))) { CryptReleaseContext(hCryptProv, 0); CertCloseStore(hStoreHandle, 0); CertFreeCertificateContext(certContext); free(pbCertHash); setLastError(); return false; } if(!CryptMsgUpdate(cryptMsg, signedMessage, signedMessageSize, TRUE)) { CryptReleaseContext(hCryptProv, 0); CertCloseStore(hStoreHandle, 0); CertFreeCertificateContext(certContext); free(pbCertHash); setLastError(); return false; } CMSG_SIGNER_ENCODE_INFO *signerInfo; memset(signerInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO)); signerInfo->cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO); signerInfo->pCertInfo = certContext->pCertInfo; signerInfo->hCryptProv = hCryptProv; signerInfo->cAuthAttr = 0; signerInfo->cUnauthAttr = 0; signerInfo->dwKeySpec = AT_SIGNATURE; signerInfo->HashAlgorithm = certContext->pCertInfo->SignatureAlgorithm; signerInfo->pvHashAuxInfo = NULL; signerInfo->rgAuthAttr = NULL; signerInfo->rgUnauthAttr = NULL; // Вот тут вылетает в ретурн с ошибкой "Операция завершена успешно"!!!! Как так? if (!CryptMsgControl(cryptMsg, 0, CMSG_CTRL_ADD_SIGNER, signerInfo)) { CryptReleaseContext(hCryptProv, 0); CertCloseStore(hStoreHandle, 0); CertFreeCertificateContext(certContext); free(pbCertHash); setLastError(); return false; } if (!CryptMsgGetParam(cryptMsg, CMSG_ENCODED_MESSAGE, 0, cosignedMessageBlob, cosignedMessageBlobSize)) { CryptReleaseContext(hCryptProv, 0); CertCloseStore(hStoreHandle, 0); CertFreeCertificateContext(certContext); free(pbCertHash); setLastError(); return false; } CryptReleaseContext(hCryptProv, 0); CertCloseStore(hStoreHandle, 0); CertFreeCertificateContext(certContext); free(pbCertHash); return true; } | ||||
| ||||
С флагом CRYPT_VERIFYCONTEXT можно проверять подпись, но никак уж не подписывать. Вам нужен хэндл именно того контейнера, секретным ключем которого вы будете доподписывать. | ||||
| ||||
Это само собой понятно (случайно написалось). Изменил ну другой флаг. Разницы нет, всё равно не работает. Ошибка: "Ключ не существует" | ||||
| ||||
А signerInfo->HashAlgorithm = certContext->pCertInfo->SignatureAlgorithm? Алгортим хеширования сообщения и алгортим, которым пописан сертификат - это совсем не одно и тоже. Ключ не существует - значит в указанном контейнере нет секретного ключа AT_SIGNATURE. | ||||
| ||||
а как получить signerInfo->HashAlgorithm? | ||||
| ||||
Посмотреть, какие алгортимы подписи поддерживает hCryptProv, если использовать ОК из сертификата. | ||||
| ||||
Что то не совсем понимаю, что имеете в виду. что за "OK" ? | ||||
| ||||
ОК - открытый ключ, имеется ввиду его алгоритм. | ||||