| ||||
| ||||
Здравствуйте! Требуется подписать в своей программе некоторую строку текста из файла и добавить подпись в конец этого файла. Причем подпись должна быть в формате PKCS#7, и в ней должна содержаться информация о сертификате подписчика (имя, орг-ция и т.д.) - я так понимаю файлы с таким содержимым (.p7s) создает CryptoARM. Но мне это надо сделать средствами CryptoAPI с помощью CryptoPRO. Это осуществимо штатными средствами криптопровайдера? Если да, то какими? Или надо самому ручками создавать подпись со структурой, как в p7s? | ||||
Ответы: | ||||
| ||||
Средствами CryptoAPI это будет сделать проще. Посмотрите CryptSignMessage | ||||
| ||||
Именно так - "средствами CryptoAPI с помощью CryptoPRO". Т.е. Вы в программе вызываете нужные функции CryptoAPI. Чем выше уровень вызываемых функций, тем меньше Вам работы как программису (но и меньше возможностей для настроек). Посмотрите готовый пример в описании в MSDN ф-и CryptSignMessage. | ||||
| ||||
Я так и сделал, по примерам с помощью данной функции реализовал подпись. Получаю 64-байтовую последовательность (? каждый раз почему то разную ?), которая просто является самой подписью. Мне нужно включать к неё также информацию из сертификата (если посмотреть получаемые cryptoarm файлы .p7s, то в них она как раз есть, а также есть, видимо, и открытый ключ подписавшего? ). Я насколько понимаю формат PKCS#7 - это именно то, что мне нужно. Вопрос собственно именно в этом - можно ли создать подпись сразу в этом формате? | ||||
| ||||
CryptSignMessage именно это и должна делать. Можете свой пример кода привести? | ||||
| ||||
Пожалуйста: BYTE *data= (BYTE *)"The data that is to be hashed and signed."; HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; if(!CryptAcquireContext(&hProv, NULL, NULL, 75, 0)) { // обработка ошибки return; } if(!CryptCreateHash(hProv, CALG_GR3411, 0, 0, &hHash)) { // обработка ошибки CryptReleaseContext(hProv, 0); return; } DWORD cbHash = 0; if(!CryptGetHashParam(hHash, HP_OID, NULL, &cbHash, 0)) { // обработка ошибки CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); return; } BYTE *pbHash = (BYTE *)malloc(cbHash); if(!CryptGetHashParam(hHash, HP_OID, pbHash, &cbHash, 0)) { // обработка ошибки CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); return; } if(!CryptHashData(hHash, data, sizeof(data), 0)) { // обработка ошибки CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); return; } DWORD dwSigLen = 0; if(!CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSigLen)) { // обработка ошибки CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); return; } BYTE *pbSignature; pbSignature = (BYTE *)malloc(dwSigLen); if(!CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, pbSignature, &dwSigLen)) { // обработка ошибки CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); return; } free(pbHash); free(pbSignature); CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); Собсно, в pbSignature получаем непонятно что и каждый раз новое... :( Отрабатывается все без ошибок. Конечно, не сомневаюсь, что где-то моя ошибка, а где - никак не пойму... | ||||
| ||||
Нескромный вопрос, Антон, а Вы вообще читали то, что Вам ответили и Василий и я? Разговор шел не про набор низкоуровневых функций а про вполне конкретную CryptSignMessage, которая делает все то же что и Ваш код + выдает нужный Вам PKCS7. То, что подпись каждый раз разная это абсолютно верно и заложено в самом алгоритме подписи. | ||||
| ||||
Приношу свои извинения, господа! Совсем заработался и не нашел отличий между CryptSignHash и CryptSignMessage... Большое спасибо за помощь и ещё раз извините за невнимательность! :) Будем копать CryptSignMessage... | ||||