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

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline Евгений Тонишев  
#1 Оставлено : 19 июля 2018 г. 17:55:41(UTC)
Евгений Тонишев

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

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

Сказал(а) «Спасибо»: 1 раз
Всем дня доброго!
Имеется код, написанный на Delphi

Код:
Utils:=CreateOleObject('CAPICOM.Utilities');
Signer.Certificate := Crt;
SignedData.Content:= Utils.HexToBinary(ToCAPICOM(input));
podpis := SignedData.Sign(Signer, false, 0);


Разработчик преобразует строку сначала в Utf8 (в шестнадцатеричном виде), потом подписывает данные подобным образом, применяя при этом преобразование в двоичный вид. Я знаю, что в Delphi на каждый символ приходится 2 байта, т.е. используется кодировка UCS-2. Пожалуйста, подскажите, как подобное написать в C++? Как взять нужный сертификат и подписать им - я знаю. Все работает, пока не нужно подписывать кириллицу. Как только в подписи есть знаки кириллицы - сервис перестает принимать мою подпись.
Offline Андрей Писарев  
#2 Оставлено : 19 июля 2018 г. 21:12:24(UTC)
Андрей *

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

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

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

Преобразования нужны,т.к. там widestring в COM.

А насчет примеров - в SDK
https://www.cryptopro.ru...downloads#latest_csp40r3
Цитата:

Документация для разработчиков и примеры (SDK)
Техническую поддержку оказываем тут
Наша база знаний
Offline Евгений Тонишев  
#3 Оставлено : 20 июля 2018 г. 16:08:04(UTC)
Евгений Тонишев

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

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

Сказал(а) «Спасибо»: 1 раз
Автор: Андрей Писарев Перейти к цитате
Преобразования нужны,т.к. там widestring в COM.

Т.е. при использовании C++ и функции CadesSignMessage подобные преобразования не нужны?
Offline Андрей Писарев  
#4 Оставлено : 20 июля 2018 г. 21:14:39(UTC)
Андрей *

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

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

Сказал «Спасибо»: 494 раз
Поблагодарили: 2035 раз в 1579 постах
Автор: Евгений Тонишев Перейти к цитате
Автор: Андрей Писарев Перейти к цитате
Преобразования нужны,т.к. там widestring в COM.

Т.е. при использовании C++ и функции CadesSignMessage подобные преобразования не нужны?


Передавать необходимо байты, как есть.
Техническую поддержку оказываем тут
Наша база знаний
Offline Евгений Тонишев  
#5 Оставлено : 20 июля 2018 г. 22:44:58(UTC)
Евгений Тонишев

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

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

Сказал(а) «Спасибо»: 1 раз
Автор: Андрей Писарев Перейти к цитате
Передавать необходимо байты, как есть.

Всё равно слабо понял этот момент. Ладно, спасибо за подсказки, буду дальше Интернеты рыть.
Offline Андрей Писарев  
#6 Оставлено : 21 июля 2018 г. 0:07:46(UTC)
Андрей *

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

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

Сказал «Спасибо»: 494 раз
Поблагодарили: 2035 раз в 1579 постах
Delphi через COM, без преобразований, читаем в Buffer из файла:
Код:
 

Buffer: WideString;
...
FileStm = TFileStream.Create(...)
 Buffer = SysAllocStringByteLen(размер файла)
 FileStm.ReadBuffer(Buffer, размер файла)
   SignedData.Content:=Buffer;



Примеры на C++ в SDK или в MSDN - пример
Техническую поддержку оказываем тут
Наша база знаний
Offline Андрей Писарев  
#7 Оставлено : 21 июля 2018 г. 0:24:14(UTC)
Андрей *

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

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

Сказал «Спасибо»: 494 раз
Поблагодарили: 2035 раз в 1579 постах
Автор: Евгений Тонишев Перейти к цитате
Автор: Андрей Писарев Перейти к цитате
Передавать необходимо байты, как есть.

Всё равно слабо понял этот момент. Ладно, спасибо за подсказки, буду дальше Интернеты рыть.


Необходимо корректно передавать на вход функции данные.
Обычно это основная проблема, если не смотреть работающие примеры, с кодировкой, например.

Также, если требуется подписывать файлы больше, например, 5-10 мб - лучше использовать поточные криптографические функции.
В данном случае смотреть примеры с
CryptMsgOpenToEncode\CryptMsgOpenToDecode, CryptMsgUpdate,

заодно и прогресс в % подписи больших файлов можно визуализировать.
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Андрей * за этот пост.
Евгений Тонишев оставлено 21.07.2018(UTC)
Offline Евгений Тонишев  
#8 Оставлено : 23 июля 2018 г. 14:38:52(UTC)
Евгений Тонишев

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

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

Сказал(а) «Спасибо»: 1 раз
Автор: Андрей Писарев Перейти к цитате
Delphi через COM, без преобразований, читаем в Buffer из файла:

Я правильно понимаю, что в Вашем примере ключевым является использование WideString вместо String? Если так, то Ваш код не работает в моё случае без дополнительных преобразований.
На сайте, где я пытаюсь проверить подпись, перед тем, как подписывать данные, производятся следующие преобразования данных:
Код:
function _to_utf8_hex(s) {
    var c, d = "";
    for (var i = 0; i < s.length; i++) {
        c = s.charCodeAt(i);
        if (c <= 0x7f) {
            d += _to_hex(c)
        } else if (c >= 0x80 && c <= 0x7ff) {
            d += _to_hex(((c >> 6) & 0x1f) | 0xc0);
            d += _to_hex((c & 0x3f) | 0x80)
        } else {
            d += _to_hex((c >> 12) | 0xe0);
            d += _to_hex(((c >> 6) & 0x3f) | 0x80);
            d += _to_hex((c & 0x3f) | 0x80)
        }
    };
    return d
}

и затем они подписываются подобным образом
Код:
function SignTextWorker(SigData, Signer, silent, data) {
    if (data.convert_to_utf8 == 1) {
        var CU = getCAPICOMObject("Utilities"),
            text = _to_utf8_hex(data.text);
        if (text.length % 4) text += '00';
        SigData.Content = CU.HexToBinary(text)
    } else SigData.Content = data.text;
    return SigData.Sign(Signer, false, CAPICOM_ENCODE_BASE64)
}

Я так понимаю, это связано с тем, что плагин для браузера не умеет напрямую работать с двоичными данными, о чем написано в данной статье.
Я сделал такое же преобразование в Delphi:
Код:
function ToCAPICOM(input: string) : string;
var
  ch: Char;
  i, code: Integer;

begin
  Result := '';
  for i := 1 to input.Length do
  begin
    code := Ord(input[i]);

    if code <= 127 then
    begin
      Result := Result + IntToHex(code, 2);
    end
    else if (code >= 128) and (code <= 2047) then
    begin
      Result := Result + IntToHex((((code shr 6) and 31) or 192), 2);
      Result := Result + IntToHex(((code and 63) or 128), 2);
    end
    else
    begin
      Result := Result + IntToHex(((code shr 12) or 224), 2);
      Result := Result + IntToHex((((code shr 6) and 63) or 128), 2);
      Result := Result + IntToHex(((code and 63) or 128), 2);
    end;

  end;

  if Result.Length mod 4 > 0 then
  begin
    Result := Result + '00';
  end;
end;


 //Подпись
function podpis(input: String) : String;
begin

    Utils:=CreateOleObject('CAPICOM.Utilities');
    Signer.Certificate := Crt;
    SignedData.Content:= Utils.HexToBinary(ToCAPICOM(input));
    podpis := SignedData.Sign(Signer, false, 0);

end;

Все заработало. Без преобразования с помощью функции ToCAPICOM подпись формируется неверно и сайт ее отклоняет. Так же, как я выше говорил, не работает вариант с WideString. Вопрос же состоит в том, как подобные преобразования написать на C++?
Автор: Андрей Писарев Перейти к цитате
Обычно это основная проблема

Тяжелая тема, если честно. :(
Offline Андрей Писарев  
#9 Оставлено : 23 июля 2018 г. 14:43:10(UTC)
Андрей *

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

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

Сказал «Спасибо»: 494 раз
Поблагодарили: 2035 раз в 1579 постах
Цитата:
Вопрос же состоит в том, как подобные преобразования написать на C++?


Из SDK на C++ не работают примеры?
Техническую поддержку оказываем тут
Наша база знаний
Offline Евгений Тонишев  
#10 Оставлено : 23 июля 2018 г. 14:44:54(UTC)
Евгений Тонишев

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

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

Сказал(а) «Спасибо»: 1 раз
Автор: Андрей Писарев Перейти к цитате
Из SDK на C не работают примеры?

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