Пример создания подписанного сообщения с помощью упрощённых функций КриптоПро ЭЦП SDK по хэш-значению. Полный текст примера см. SDK файл SimplifiedSignHashCades.cpp.
C++
CRYPT_SIGN_MESSAGE_PARA signPara = {sizeof(signPara)}; signPara.dwMsgEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; signPara.pSigningCert = context; signPara.HashAlgorithm.pszObjId = (LPSTR) GetHashOid(context); CADES_SERVICE_CONNECTION_PARA tspConnectionPara = { sizeof(tspConnectionPara)}; tspConnectionPara.wszUri = SERVICE_URL_2012; // Адрес веб - сервиса со службой штампов времени CADES_SIGN_PARA cadesSignPara = {sizeof(cadesSignPara)}; cadesSignPara.dwCadesType = CADES_X_LONG_TYPE_1; // Указываем тип усовершенствованной подписи // CADES_X_LONG_TYPE_1 cadesSignPara.pTspConnectionPara = &tspConnectionPara; CADES_SIGN_MESSAGE_PARA para = {sizeof(para)}; para.pSignMessagePara = &signPara; para.pCadesSignPara = &cadesSignPara; // Формируем данные для подписания vector<unsigned char> data(10, 25); // Получение хэша данных HCRYPTHASH hash(0); if (!CryptCreateHash(hProv, CALG_GR3411_2012_256, 0, 0, &hash)) { CryptReleaseContext(hProv, 0); CertFreeCertificateContext(context); cout << "CryptCreateHash() failed" << endl; return -1; } DWORD cbToBeSigned(0); DWORD cb = sizeof(cbToBeSigned); BYTE *pbToBeSigned; switch (CryptHashData(hash, &data[0], (DWORD) data.size(), 0)) { case TRUE: if (!CryptGetHashParam(hash, HP_HASHSIZE, (LPBYTE) &cbToBeSigned, &cb, 0)) { CryptDestroyHash(hash); CryptReleaseContext(hProv, 0); CertFreeCertificateContext(context); cout << "CryptGetHashParam() failed" << endl; return -1; } pbToBeSigned = new BYTE[cbToBeSigned]; if (!CryptGetHashParam(hash, HP_HASHVAL, pbToBeSigned, &cbToBeSigned, 0)) { delete[] pbToBeSigned; CryptDestroyHash(hash); CryptReleaseContext(hProv, 0); CertFreeCertificateContext(context); cout << "CryptGetHashParam() failed" << endl; return -1; } break; default: CryptDestroyHash(hash); CryptReleaseContext(hProv, 0); CertFreeCertificateContext(context); cout << "CryptHashData() failed" << endl; return -1; } PCRYPT_DATA_BLOB pSignedMessage = 0; string contentType(szOID_RSA_data); // Создаем подписанное сообщение if (!CadesSignHash(¶, pbToBeSigned, cbToBeSigned, contentType.c_str(), &pSignedMessage)) { delete[] pbToBeSigned; CryptDestroyHash(hash); CryptReleaseContext(hProv, 0); CertFreeCertificateContext(context); cout << "CadesSignHash() failed" << endl; return -1; } delete[] pbToBeSigned; vector<unsigned char> message(pSignedMessage->cbData); copy(pSignedMessage->pbData, pSignedMessage->pbData + pSignedMessage->cbData, message.begin());