Статус: Участник
Группы: Участники
Зарегистрирован: 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++? Автор: Андрей Писарев Обычно это основная проблема Тяжелая тема, если честно. :(
|