| ||||
| ||||
Имею код: ////////////////////////////////////// CMSG_STREAM_INFO stream = {}; stream.cbContent = 0xFFFFFFFF; stream.pfnStreamOutput = SavingCallback; stream.pvArg = (void*)pobjOutFile; HCRYPTPROV hProv = NULL; DWORD dwKeySpec = NULL; BOOL bFree = FALSE; if (!CryptAcquireCertificatePrivateKey(*pobjSign, 0, NULL, &hProv, &dwKeySpec, &bFree)) { //Исключение } if (hProv == NULL) { //Исключение } CMSG_SIGNER_ENCODE_INFO signerInfo; CMSG_SIGNER_ENCODE_INFO signerInfoArray[1]; memset(&signerInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO)); signerInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO); signerInfo.pCertInfo = ((PCCERT_CONTEXT)pobjSign)->pCertInfo; signerInfo.hCryptProv = hProv; signerInfo.dwKeySpec = dwKeySpec; signerInfo.HashAlgorithm.pszObjId = (LPSTR)(pobjSign->GetHashOID().c_str()); signerInfo.pvHashAuxInfo = NULL; signerInfoArray[0] = signerInfo; CMSG_SIGNED_ENCODE_INFO info; memset(&info, 0, sizeof(CMSG_SIGNED_ENCODE_INFO)); info.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO); info.cSigners = 1; info.rgSigners = signerInfoArray; HCRYPTMSG hMsg = CryptMsgOpenToEncode(MY_ENCODING_TYPE, 0, CMSG_SIGNED, &info, 0, &stream); ///////////////////////////////////////////// Получаем hMsg равным нулю. GetLastError() даёт ошибку 0x80090020 (Внутренняя ошибка) Что здесь реализовано неправильно? Если подписывать при помощи CryptSignMessage подпись ставится. Но мне нужна именно работа с потоками. | ||||
Ответы: | ||||
| ||||
Буду благодарен за любую помощь. По-моему, в csptest и MSDN аналогично сделано, но не понятно, почему в моём коде выдаёт Внутреннюю Ошибку? У меня КриптоПро CSP 2.0 (Build 2089) | ||||
| ||||
А что такое pobjSign? | ||||
| ||||
pobjSign - это указатель на наш класс, инкапсулирующий работу с подписями. Операция ((PCCERT_CONTEXT)pobjSign) просто возвращает член класса, который объявлен так: PCCERT_CONTEXT pSignerCert; pobjSign->GetHashOID() возвращает член класса std::basic_string<char> saHashOID, который просто инициализируется в конструкторе. Я изменил строку на signerInfo.HashAlgorithm.pszObjId = (LPSTR)(pobjSign->GetHashOID().data()); Всё равно возникает внутренняя ошибка. | ||||
| ||||
В нашем случае signerInfo.HashAlgorithm.pszObjId принимает значение, например, "1.2.643.2.2.9" | ||||
| ||||
А без CMSG_STREAM_INFO работает? | ||||
| ||||
Нет, если вместо него передать в CryptMsgOpenToEncode значение NULL, та же самая ошибка. Если делать через CryptSignMessage(), работает. | ||||
| ||||
_Эта_ проблема решена. Оказывается, я забыл взять значение по адресу: PCCERT_CONTEXT(*pobjSign)->pCertInfo; Такую ерунду не заметил :) Спасибо за помощь! | ||||
| ||||
Уважаемый, Jar! Не могли бы Вы проконсультировать по поводу использования потоков при операциях подписи/шифрования. Почитал MSDN - голову сломал. Если не трудно, вышлите хотя бы скелет функции, которую вы здесь привели. Меня интересует порядок вызовов функций CryptoAPI при работе с потоками, а также выставленные флаги и размеры буферов... Заранее спасибо! rysev@inbox.ru | ||||
| ||||
А вот в MSDN есть пример тоже http://msdn2.microsoft.com/en-us/library/aa382381.aspx | ||||
| ||||
О, замечательно. Кирилл, спасибо! Меня вот какой вопрос ещё интересует. В MSDN в описаниях функций CryptMsg* используется термин "encoding", в то время как в прочих функциях - "encrypting". Это тождественно по функциональному наполнению? | ||||
| ||||
Нет, это разные вещи. Под encoding в CryptoAPI подразумевается кодирование в криптографические форматы, под encrypting - исключительно шифрование. | ||||
| ||||
А почему в Вашем примере csptest в исходном коде в комментариях говорится о шифровании при использовании CryptMsg*? Или я чего-то недопонимаю? Спасибо | ||||
| ||||
Потому что с помощью CryptMsg* можно как шифровать, так и кодировать результат в криптографический формат. Как и в функции CryptEncryptMessage. MSDN: The CryptEncryptMessage function encrypts and encodes a message. А вот функция CryptEncrypt умеет только шифровать, кодировать она не умеет. | ||||
| ||||
Иван, К сожалению мы пока отказались от поддержки потоков, т.к. была затруднена поддержка некоторых функций. Но если будут конкретные вопросы по работе с потоками, если смогу постараюсь помочь... | ||||