Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline Хемуль Хемулевский  
#1 Оставлено : 8 октября 2025 г. 15:27:02(UTC)
Хемуль Хемулевский

Статус: Участник

Группы: Участники
Зарегистрирован: 11.12.2024(UTC)
Сообщений: 10
Российская Федерация
Откуда: Москва

Коллеги добрый день. Помогите разобраться как установить комбинированный алгоритм подписи в параметр HashEncryptionAlgorithm.

Пытаюсь установить следующим образом, но алгоритм на выходе почему то всегда берётся из публичного ключа.

Код:
EncodedTime signTime = getCurrentEncodedTime();
result.date = signTime.localTime;
CRYPT_ATTR_BLOB attrBlob;
CRYPT_ATTRIBUTE attr;
attrBlob.cbData = signTime.asn1Data.size();
attrBlob.pbData = signTime.asn1Data.data();
attr.pszObjId = (LPSTR)szOID_RSA_signingTime;
attr.cValue = 1;
attr.rgValue = &attrBlob;

CRYPT_SIGN_MESSAGE_PARA stSignMessagePara;
DWORD MessageSizeArray[1];
const BYTE* MessageArray[1];
CRYPT_OBJID_BLOB hashParam;
hashParam.cbData = 0;
hashParam.pbData = nullptr;
CRYPT_ALGORITHM_IDENTIFIER hashAlgo;
CRYPT_ALGORITHM_IDENTIFIER signAlgo;
hashAlgo.pszObjId = (LPSTR)szOID_CP_GOST_R3411_12_512;
signAlgo.pszObjId = (LPSTR)szOID_CP_GOST_R3411_12_512_R3410;
hashAlgo.Parameters = hashParam;
signAlgo.Parameters = hashParam;

ZeroMemory(&stSignMessagePara, sizeof(CRYPT_SIGN_MESSAGE_PARA));
stSignMessagePara.cbSize = sizeof(stSignMessagePara);
stSignMessagePara.dwMsgEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
stSignMessagePara.pSigningCert = pCertCtx_;
stSignMessagePara.HashAlgorithm= hashAlgo;
stSignMessagePara.pvHashAuxInfo = nullptr;
stSignMessagePara.HashEncryptionAlgorithm = signAlgo;
stSignMessagePara.pvHashEncryptionAuxInfo = nullptr;
stSignMessagePara.rgpMsgCert = &pCertCtx_;
stSignMessagePara.cMsgCert = 1;
stSignMessagePara.cAuthAttr = 1;
stSignMessagePara.rgAuthAttr = &attr;
MessageArray[0] = (const BYTE*)datatosing.bytes();
MessageSizeArray[0] = datatosing.length;

CryptSignMessage(
&stSignMessagePara, 
TRUE, 
1, 
MessageArray, 
MessageSizeArray, 
NULL, 
&dwSignatureSize)


Пробовал сделать тоже самое через CryptMsgOpenToEncode и структуру CMSG_SIGNER_ENCODE_INFO но результат оказался таким же.
А алгоритм поменять нужно так как при последующей проверке на другой системе, где используется JCP получаю ошибку вида:

java.security.NoSuchAlgorithmException: no such algorithm: 1.2.643.7.1.1.1.2 for provider JCSP

Имел опыт только с JCP там можно задавать параметры digest и sign (JCP.GOST_DIGEST_2012_512_OID и JCP.GOST_SIGN_2012_512_OID), а как сделать тоже самое в cpapilite разобраться не могу...

Отредактировано пользователем 8 октября 2025 г. 15:38:38(UTC)  | Причина: Не указана

Offline Андрей *  
#2 Оставлено : 8 октября 2025 г. 16:14:59(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 13,961
Мужчина
Российская Федерация

Сказал «Спасибо»: 602 раз
Поблагодарили: 2342 раз в 1839 постах
Здравствуйте.

В сертификате указано и из него должно использоваться.

1.2.643.7.1.1.1.1 - алгоритм подписи ГОСТ Р 34.10-2012 с ключом 256 - в квал.сертификатах
1.2.643.7.1.1.1.2 - алгоритм подписи ГОСТ Р 34.10-2012 с ключом 512


Почему потребовался ключ 512?

Техническую поддержку оказываем тут
Наша база знаний
Offline Хемуль Хемулевский  
#3 Оставлено : 8 октября 2025 г. 16:40:22(UTC)
Хемуль Хемулевский

Статус: Участник

Группы: Участники
Зарегистрирован: 11.12.2024(UTC)
Сообщений: 10
Российская Федерация
Откуда: Москва

Началось с того что при проверки подписи на другой системе где используется JCSP и проверка проходит через java.security.signature получаю ошибку: java.security.NoSuchAlgorithmException: no such algorithm: 1.2.643.7.1.1.1.2 for provider JCSP. Она происходит в тот момент когда Signature обращается к JCSP и не находит там алгоритма 1.2.643.7.1.1.1.2. В этот момент я пошел посмотреть как реализован выбор алгоритма на других системах, от которых данная проверка проходит успешно и нашел там следующую java реализацию:

Код:

        switch (keyAlgoritm) {

            case JCP.GOST_EL_2012_512_NAME:
            case JCP.GOST_DH_2012_512_NAME:

                signAlg = JCP.GOST_SIGN_2012_512_NAME;
                digestOidValue = JCP.GOST_DIGEST_2012_512_OID;
                signOidValue = JCP.GOST_SIGN_2012_512_OID;
                digestAlg = JCP.GOST_DIGEST_2012_512_NAME;
                break;
            case JCP.GOST_EL_2012_256_NAME:
            case JCP.GOST_DH_2012_256_NAME:

                signAlg = JCP.GOST_SIGN_2012_256_NAME;
                digestOidValue = JCP.GOST_DIGEST_2012_256_OID;
                digestAlg = JCP.GOST_DIGEST_2012_256_NAME;
                signOidValue = JCP.GOST_SIGN_2012_256_OID;
                break;
            case JCP.GOST_EL_SIGN_NAME:
            case JCP.GOST_DHEL_SIGN_NAME:
                signAlg = JCP.GOST_EL_SIGN_NAME;
                digestOidValue = JCP.GOST_DIGEST_OID;
                signOidValue = JCP.GOST_EL_SIGN_OID;
                break;
        }
    }

И если я правильно понимаю провайдер JCSP ожидает алгоритм 1.2.643.7.1.1.3.3 а не 1.2.643.7.1.1.1.2 в поле алгоритма подписи.

Отредактировано пользователем 8 октября 2025 г. 20:01:37(UTC)  | Причина: Не указана

Offline Хемуль Хемулевский  
#4 Оставлено : 10 октября 2025 г. 12:41:28(UTC)
Хемуль Хемулевский

Статус: Участник

Группы: Участники
Зарегистрирован: 11.12.2024(UTC)
Сообщений: 10
Российская Федерация
Откуда: Москва

Автор: Андрей * Перейти к цитате
Здравствуйте.

В сертификате указано и из него должно использоваться.

1.2.643.7.1.1.1.1 - алгоритм подписи ГОСТ Р 34.10-2012 с ключом 256 - в квал.сертификатах
1.2.643.7.1.1.1.2 - алгоритм подписи ГОСТ Р 34.10-2012 с ключом 512


Почему потребовался ключ 512?



Здравствуйте. Такие ключи выпускает наш уц. Есть какие то соображение по проблеме? я так понимаю что jcsp ищет алгоритм подписи (1.2.643.7.1.1.3.3), но находит в нужном месте алгоритм ключа вместо него и дальше выкидывает ошибку. А как с помощью cpapilite установить нужный алгоритм подписи я не разобрался к сожалению.

Отредактировано пользователем 10 октября 2025 г. 12:44:01(UTC)  | Причина: Не указана

Offline Евгений Афанасьев  
#5 Оставлено : 10 октября 2025 г. 12:54:19(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 4,061
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 738 раз в 696 постах
Добрый день.
Приведите, пожалуйста, пример, что делаете и стек ошибки, которая возникает.
Offline Хемуль Хемулевский  
#6 Оставлено : 10 октября 2025 г. 13:33:21(UTC)
Хемуль Хемулевский

Статус: Участник

Группы: Участники
Зарегистрирован: 11.12.2024(UTC)
Сообщений: 10
Российская Федерация
Откуда: Москва

Автор: Евгений Афанасьев Перейти к цитате
Добрый день.
Приведите, пожалуйста, пример, что делаете и стек ошибки, которая возникает.


Подпись выполняю следующим образом:
Код:
 EncodedTime signTime = getCurrentEncodedTime();
        result.date = signTime.localTime;
        CRYPT_ATTR_BLOB attrBlob{};
        CRYPT_ATTRIBUTE attr{};
        attrBlob.cbData = signTime.asn1Data.size();
        attrBlob.pbData = signTime.asn1Data.data();
        attr.pszObjId = (LPSTR)szOID_RSA_signingTime;
        attr.cValue = 1;
        attr.rgValue = &attrBlob;
        
        CRYPT_OBJID_BLOB emptyParam;
        emptyParam.cbData = 0;
        emptyParam.pbData = nullptr;
        CRYPT_ALGORITHM_IDENTIFIER hashAlgo{};
        CRYPT_ALGORITHM_IDENTIFIER signAlgo{};
        [b]hashAlgo.pszObjId = (LPSTR)szOID_CP_GOST_R3411_12_512;
        signAlgo.pszObjId = (LPSTR)szOID_CP_GOST_R3411_12_512_R3410[/b];
        signAlgo.Parameters = emptyParam;
        hashAlgo.Parameters = emptyParam;

        CMSG_SIGNER_ENCODE_INFO signer{};
        signer.cbSize = sizeof(signer);
        signer.pCertInfo = pCertCtx_->pCertInfo;
        signer.hCryptProv = hProv;
        signer.dwKeySpec = dwKeySpec;
        signer.HashAlgorithm = hashAlgo;
        signer.HashEncryptionAlgorithm = signAlgo;
        signer.pvHashAuxInfo = nullptr;
        signer.pvHashEncryptionAuxInfo = nullptr;
        signer.cAuthAttr = 1;
        signer.rgAuthAttr = &attr;

        CMSG_SIGNED_ENCODE_INFO signedInfo{};
        signedInfo.cbSize = sizeof(signedInfo);
        signedInfo.cSigners = 1;
        signedInfo.rgSigners = &signer;
        signedInfo.cCertEncoded = 0;
        signedInfo.rgCertEncoded = NULL;

        hMsg = CryptMsgOpenToEncode(
            PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
            CMSG_DETACHED_FLAG,   
            CMSG_SIGNED,
            &signedInfo,
            NULL,
            NULL
        );
        
        CryptMsgUpdate(hMsg, reinterpret_cast<const BYTE*>(dataToSign.bytes()), dataToSign.length, TRUE)


Дальше проверка подписи выполняется на другой системе с помощью JCSP:

Код:
Asn1BerDecodeBuffer asnBuf = new Asn1BerDecodeBuffer(signature);
ContentInfo all = new ContentInfo();
       all.decode(asnBuf);
        if (!new OID(CmsSigner.STR_CMS_OID_SIG).eq(all.contentType.value)) {
                throw new Exception("Not supported");
            } 
          SignedData cms = (SignedData) all.content;
            if (document == null) {
                throw new Exception("No content for verify");
            }   
            if (cms.certificates != null) {
                Asn1BerEncodeBuffer encBuf = new Asn1BerEncodeBuffer();
                cms.certificates.elements[0].encode(encBuf);
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                X509Certificate cert = (X509Certificate) cf.generateCertificate(encBuf.getInputStream());
com.objsys.asn1j.pkcs7.SignerInfo info = cms.signerInfos.elements[0];
OID sigOid = new OID(info.signatureAlgorithm.algorithm.value);
        java.security.Signature signature = Signature.getInstance(sigOid.toString(), JCSP.PROVIDER_NAME);
        signature.initVerify(certificate);
        signature.update(data);
        

на моменте Signature.getInstance получаю ошибку java.security.NoSuchAlgorithmException: no such algorithm: 1.2.643.7.1.1.1.2 for provider JCSP
Если посмотреть что попало в подпись следующим способом:
Код:
HCRYPTMSG hMsg = CryptMsgOpenToDecode( PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);     
    CryptMsgUpdate(hMsg, signature.data(), signature.size(), TRUE);
    DWORD cbData = 0;
    CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &cbData);
    std::vector<BYTE> buffer(cbData);
    CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, buffer.data(), &cbData);
    CMSG_SIGNER_INFO* pInfo = (CMSG_SIGNER_INFO*)buffer.data();
    std::cout << "Signature Algorithm OID: "
        << pInfo->HashEncryptionAlgorithm.pszObjId << std::endl;
    CryptMsgClose(hMsg);


Получаю тот же алгоритм ключа 1.2.643.7.1.1.1.2 вместо алгоритма подписи.

Отредактировано пользователем 10 октября 2025 г. 13:39:00(UTC)  | Причина: Не указана

Offline Хемуль Хемулевский  
#7 Оставлено : 10 октября 2025 г. 15:33:45(UTC)
Хемуль Хемулевский

Статус: Участник

Группы: Участники
Зарегистрирован: 11.12.2024(UTC)
Сообщений: 10
Российская Федерация
Откуда: Москва

Автор: Евгений Афанасьев Перейти к цитате
Добрый день.
Приведите, пожалуйста, пример, что делаете и стек ошибки, которая возникает.


Основная проблема в том что алгоритм 1.2.643.7.1.1.1.2 не алгоритм подписи. А в итоговой открепленной подписи он оказывается на месте алгоритма подписи. как сказано в вашем комментарии в заголовочном файле CSP_wincrypt.h:

Цитата:
If HashEncryptionAlgorithm is present and not NULL its used instead of
the SigningCert's PublicKeyInfo.Algorithm.


Но при этом если мы даже задаем алгоритм подписи в HashEncryptionAlgorithm то это поле все равно игнорируется и подставляется алгоритм ключа.
Offline Андрей *  
#8 Оставлено : 10 октября 2025 г. 16:25:17(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 13,961
Мужчина
Российская Федерация

Сказал «Спасибо»: 602 раз
Поблагодарили: 2342 раз в 1839 постах
Автор: Хемуль Хемулевский Перейти к цитате
Автор: Евгений Афанасьев Перейти к цитате
Добрый день.
Приведите, пожалуйста, пример, что делаете и стек ошибки, которая возникает.


Основная проблема в том что алгоритм 1.2.643.7.1.1.1.2 не алгоритм подписи. А в итоговой открепленной подписи он оказывается на месте алгоритма подписи. как сказано в вашем комментарии в заголовочном файле CSP_wincrypt.h:

Цитата:
If HashEncryptionAlgorithm is present and not NULL its used instead of
the SigningCert's PublicKeyInfo.Algorithm.


Но при этом если мы даже задаем алгоритм подписи в HashEncryptionAlgorithm то это поле все равно игнорируется и подставляется алгоритм ключа.




1.2.643.7.1.1.1.2

id-tc26-gost3410-12-512

алгоритм подписи ГОСТ Р 34.10-2012 с ключом 512
Техническую поддержку оказываем тут
Наша база знаний
Offline Евгений Афанасьев  
#9 Оставлено : 10 октября 2025 г. 17:09:37(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 4,061
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 21 раз
Поблагодарили: 738 раз в 696 постах
OID алгоритма подписи с хэшом 1.2.643.7.1.1.3.2 или 1.2.643.7.1.1.3.2 указывается в сертификате. В CMS подписи задается OID открытого ключа, т.е. для CMS надо digestOid.toString() + "WITH" + sigOid.toString(), а не просто sigOid.toString().
Offline Хемуль Хемулевский  
#10 Оставлено : 11 октября 2025 г. 0:01:39(UTC)
Хемуль Хемулевский

Статус: Участник

Группы: Участники
Зарегистрирован: 11.12.2024(UTC)
Сообщений: 10
Российская Федерация
Откуда: Москва

Автор: Евгений Афанасьев Перейти к цитате
OID алгоритма подписи с хэшом 1.2.643.7.1.1.3.2 или 1.2.643.7.1.1.3.2 указывается в сертификате. В CMS подписи задается OID открытого ключа, т.е. для CMS надо digestOid.toString() + "WITH" + sigOid.toString(), а не просто sigOid.toString().


Евгений, понял вас. Но может есть вариант задать алгоритм подписи, как например в java? Очень будет тяжело менять уже реализованную валидацию в другой системе, я бы даже сказал не возможно)

В заголовочном файле csp_wincrypt сказано:
Цитата:
If HashEncryptionAlgorithm is present and not NULL its used instead of
the SigningCert's PublicKeyInfo.Algorithm.

Но я правильно понимаю что это осталось от Windows CryptoAPI но не реализовано?

Вот как в java задавали алгоритм подписи в CMS, до перехода на С++:

Код:

digestOidValue = JCP.GOST_DIGEST_2012_512_OID;
signOidValue = JCP.GOST_SIGN_2012_512_OID;
final SignedData cms = new SignedData();
cms.signerInfos.elements[0].digestAlgorithm = new DigestAlgorithmIdentifier(new OID(digestOidValue).value);
cms.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null();
cms.signerInfos.elements[0].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(signOidValue).value);
cms.signerInfos.elements[0].signatureAlgorithm.parameters = new Asn1Null();

       final Asn1Type messageDigest = new Asn1OctetString(messageDigestBlob);
       cms.signerInfos.elements[0].signedAttrs.elements[1].values.elements[0] = messageDigest;

       // signature
       Asn1BerEncodeBuffer encBufSignedAttr = new Asn1BerEncodeBuffer();
       cms.signerInfos.elements[0].signedAttrs.encode(encBufSignedAttr);
        final java.security.Signature signature = java.security.Signature.getInstance(signAlg, providerName);
        byte[] sign;
        final byte[] hSign = encBufSignedAttr.getMsgCopy();
        signature.initSign(pk);
        signature.update(hSign);
        sign = signature.sign();
        cms.signerInfos.elements[0].signature = new SignatureValue(sign);
        // encode
        final Asn1BerEncodeBuffer asn1Buf = new Asn1BerEncodeBuffer();
        all.encode(asn1Buf, true);
    

Отредактировано пользователем 11 октября 2025 г. 0:04:17(UTC)  | Причина: Не указана

RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest (2)
2 Страницы12>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.