Развернуть все
Свернуть все

Создание подписи по хэш-значению (упрощённые функции)

Пример создания подписанного сообщения с помощью упрощённых функций КриптоПро ЭЦП 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)szOID_CP_GOST_R3411; // Хэш считается по ГОСТ Р 34.11-94

    CADES_SERVICE_CONNECTION_PARA tspConnectionPara = {
        sizeof(tspConnectionPara)};
    tspConnectionPara.wszUri =
        SERVICE_URL; // Адрес веб - сервиса со службой штампов времени

    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, 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)) {
            CryptReleaseContext(hProv, 0);
            CertFreeCertificateContext(context);
            CryptDestroyHash(hash);
            cout << "CryptGetHashParam() failed" << endl;
            return -1;
        }

        pbToBeSigned = new BYTE[cbToBeSigned];

        if (!CryptGetHashParam(hash, HP_HASHVAL, pbToBeSigned, &cbToBeSigned,
                               0)) {
            delete[] pbToBeSigned;
            CryptReleaseContext(hProv, 0);
            CertFreeCertificateContext(context);
            CryptDestroyHash(hash);
            cout << "CryptGetHashParam() failed" << endl;
            return -1;
        }
        break;
    default:
        CryptReleaseContext(hProv, 0);
        CertFreeCertificateContext(context);
        CryptDestroyHash(hash);
        cout << "CryptHashData() failed" << endl;
        return -1;
    }

    PCRYPT_DATA_BLOB pSignedMessage = 0;

    string contentType(szOID_RSA_data);

    // Создаем подписанное сообщение
    if (!CadesSignHash(&para, pbToBeSigned, cbToBeSigned, contentType.c_str(),
                       &pSignedMessage)) {
        delete[] pbToBeSigned;
        CryptReleaseContext(hProv, 0);
        CertFreeCertificateContext(context);
        CryptDestroyHash(hash);
        cout << "CadesSignHash() failed" << endl;
        return -1;
    }

    delete[] pbToBeSigned;

    vector<unsigned char> message(pSignedMessage->cbData);
    copy(pSignedMessage->pbData,
         pSignedMessage->pbData + pSignedMessage->cbData, message.begin());