Пример создания подписанного сообщения с помощью упрощённых функций КриптоПро ЭЦП 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);
CertCloseStore(hStoreHandle, 0);
cout << "CryptCreateHash() failed" << endl;
return -1;
}
DWORD cbToBeSigned(0);
DWORD cb = sizeof(cbToBeSigned);
BYTE *pbToBeSigned;
if (!CryptHashData(hash, &data[0], (DWORD)data.size(), 0)) {
CryptDestroyHash(hash);
CryptReleaseContext(hProv, 0);
CertFreeCertificateContext(context);
CertCloseStore(hStoreHandle, 0);
cout << "CryptHashData() failed" << endl;
return -1;
}
if (!CryptGetHashParam(hash, HP_HASHSIZE, (LPBYTE)&cbToBeSigned, &cb, 0)) {
CryptDestroyHash(hash);
CryptReleaseContext(hProv, 0);
CertFreeCertificateContext(context);
CertCloseStore(hStoreHandle, 0);
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);
CertCloseStore(hStoreHandle, 0);
cout << "CryptGetHashParam() 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);
CertCloseStore(hStoreHandle, 0);
cout << "CadesSignHash() failed" << endl;
return -1;
}
delete[] pbToBeSigned;
vector<unsigned char> message(pSignedMessage->cbData);
copy(pSignedMessage->pbData,
pSignedMessage->pbData + pSignedMessage->cbData, message.begin());