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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Dms  
#1 Оставлено : 6 июня 2013 г. 18:05:35(UTC)
Dms

Статус: Новичок

Группы: Участники
Зарегистрирован: 24.03.2010(UTC)
Сообщений: 4
Откуда: msk

Сказал(а) «Спасибо»: 1 раз
У меня есть данные, есть сертификат связанный с закрытым ключом - нужно сделать XMLподпись (для СМЭВ).
С++ и CryptoAPI.

Делаю канонизацию тэга, делаю хэш, записываю в DigestValue - значение правильно.
Дальше нужно подписать полученный тэг <SignedInfo>
Цитата:
3.3. Элемент SignedInfo трансформируется в соответствии с алгоритмом «http://www.w3.org/2001/10/xml-exc-c14n#». Затем на основании полученной строки и ключа подписи формируется значение ЭП в соответствии с алгоритмом «http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411». Полученное значение ЭП кодируется в соответствии с алгоритмом «http://www.w3.org/2000/09/xmldsig#base64», символы не входящие в алфавит Base64 удаляются и полученное значение добавляется как дочерний текстовый узел к элементу SignatureValue.


На входе канонизированный тэг <SignedInfo/>, как blob, length - его длина. Подпись кладется в sign. Сертификат с подходящими алгоритмами.
Я делаю следующее:
Код:
bool
Hash_n_Sign::sign(void* blob, size_t length, std::string& sign)
{
        // из бинарных данных делаю контекст сертификата
    PCCERT_CONTEXT  certContext;
    certContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (BYTE*)m_sSertificate.c_str(), m_sSertificate.length());
    if (m_certContext)
    {
        HCRYPTPROV  hCrypProv;
        DWORD       nKeyType;
        BOOL        bCallerFreeProv;
            // получаю доступ к закрытому ключу
        if (CryptAcquireCertificatePrivateKey(certContext, 0, NULL, &hCrypProv, &nKeyType, &bCallerFreeProv))
        {
            HCRYPTHASH      hHashObject;

                // Хэшируем данные
            if (CryptCreateHash(hCrypProv, getHashAlgID(), NULL, NULL, &hHashObject))
            {
                if (CryptHashData(hHash, (BYTE*)blob, length, 0))
                {
                        // Подписываем
                    DWORD   dwSigLen = 0;
                    if (CryptSignHash(hHash, keyType, NULL, 0, NULL, &dwSigLen))
                    {
                        BYTE*   pbSignature = 0;
                        if (pbSignature = (BYTE*)malloc(dwSigLen))
                        {
                            if (CryptSignHash(hHash, m_keyType, NULL, 0, pbSignature, &dwSigLen)) 
                            {
                                    // кодирую в base64 и кладу в строку
                                InternalString      hash64;
                                encode_base64((char*)pbSignature, dwSigLen, hash64, 0);
                                sign = narrow(hash64);
                                ret = true;
                            }
                            free(pbSignature);
                        }
                    }
                }
                CryptDestroyHash(hHash);
            }
            if (bCallerFreeProv)
                CryptReleaseContext(hCrypProv, 0);
        }
    }
    if (!ret)
    {
        DWORD   err = GetLastError();
    }
    return ret;
}


Но что-то я здесь делаю не так и проверку на сайте смэв моя подпись не проходит.
Взгляните незамыленным глазом, что я делаю не так.
Offline Юрий  
#2 Оставлено : 6 июня 2013 г. 20:14:06(UTC)
Юрий

Статус: Активный участник

Группы: Участники
Зарегистрирован: 22.01.2008(UTC)
Сообщений: 675
Мужчина
Российская Федерация
Откуда: Йошкар-Ола

Сказал «Спасибо»: 3 раз
Поблагодарили: 95 раз в 68 постах
Сделайте обратный порядок байт в "pbSignature". Перед кодированием в BASE-64 разумеется.
То есть первый байт сделайте последним, а последний - первым и т.д.

Поискать можно по сочетаниям "little endian" и "big endian".
С уважением,
Юрий Строжевский
Offline Dms  
#3 Оставлено : 7 июня 2013 г. 13:28:59(UTC)
Dms

Статус: Новичок

Группы: Участники
Зарегистрирован: 24.03.2010(UTC)
Сообщений: 4
Откуда: msk

Сказал(а) «Спасибо»: 1 раз
Я пробовал и 2 байта менять местами и 4,

char chs[4];
for (size_t n = 0; n < dwSigLen; n += 4)
{
memcpy(chs, pbSignature + n, 4);
pbSignature[n] = chs[3];
pbSignature[n + 1] = chs[2];
pbSignature[n + 2] = chs[1];
pbSignature[n + 3] = chs[0];
}

, но к сожалению не проходит. Может я еще что-то не так делаю?

А сам порядок подписи тэга сертификатом правильный?
Offline Юрий  
#4 Оставлено : 7 июня 2013 г. 14:25:13(UTC)
Юрий

Статус: Активный участник

Группы: Участники
Зарегистрирован: 22.01.2008(UTC)
Сообщений: 675
Мужчина
Российская Федерация
Откуда: Йошкар-Ола

Сказал «Спасибо»: 3 раз
Поблагодарили: 95 раз в 68 постах
Я делаю так:

int signature_mix(BYTE* initial, DWORD initial_size)
{
for(DWORD i = 0; i<=(initial_size/2 - 1); i++)
{
BYTE b = initial[i];
initial[i] = initial[initial_size - 1 - i];
initial[initial_size - 1 - i] = b;
}

return 0;
}

По-моему вся проблема только в этом.
С уважением,
Юрий Строжевский
thanks 1 пользователь поблагодарил Юрий за этот пост.
Dms оставлено 07.06.2013(UTC)
Offline Dms  
#5 Оставлено : 7 июня 2013 г. 16:07:10(UTC)
Dms

Статус: Новичок

Группы: Участники
Зарегистрирован: 24.03.2010(UTC)
Сообщений: 4
Откуда: msk

Сказал(а) «Спасибо»: 1 раз
Это даже не байты переставить местами, а вообще всю подпись отзеркалить.

Спасибо, добрый человек! Я был уже на пути к отчаянью.
Offline Юрий  
#6 Оставлено : 7 июня 2013 г. 16:12:10(UTC)
Юрий

Статус: Активный участник

Группы: Участники
Зарегистрирован: 22.01.2008(UTC)
Сообщений: 675
Мужчина
Российская Федерация
Откуда: Йошкар-Ола

Сказал «Спасибо»: 3 раз
Поблагодарили: 95 раз в 68 постах
Автор: Dms Перейти к цитате
Это даже не байты переставить местами, а вообще всю подпись отзеркалить.

Спасибо, добрый человек! Я был уже на пути к отчаянью.

Пожалуйста!
С уважением,
Юрий Строжевский
Offline smev  
#7 Оставлено : 27 февраля 2015 г. 7:17:12(UTC)
smev

Статус: Новичок

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

Делаю как по описанию.

у кого нибудь получилось получить подпись тега SignedInfo ?
Я уже и переставлял данные , ничего не получилось.

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