Статус: Участник
Группы: Участники
Зарегистрирован: 20.07.2021(UTC) Сообщений: 13
Сказал(а) «Спасибо»: 6 раз
|
Автор: Андрей *  Автор: tonax  Автор: Андрей *  Автор: tonax  Автор: Андрей *  На тестовой странице присоединенная подпись формируется. В чем ещё отличие? Разные результаты подписания строки, например KZEKPLILATPSQLIFKVVYILQFEPIZAWВот первая строка программное полученной подписанной строки: MIIfHwYJKoZIhvcNAQcCoIIfEDCCHwwCAQExDjAMBggqhQMHAQECAgUAMAsGCSqGSIb3DQEHAaCCА вот правильная с https://www.cryptopro.ru.../cades_bes_sample.html#: MIIfbQYJKoZIhvcNAQcCoIIfXjCCH1oCAQExDjAMBggqhQMHAQECAgUAMC0GCSqGSIb3DQEHAaAg и так в каждой строчке какие-то отличия Разные типы CMS, разный размер структур => разный base64 + в конце всегда будет разное значение ЭП. Дело в том, что честный знак не принимают программную подпись, а с https://www.cryptopro.ru...ge/cades_bes_sample.html прекрасно принимает... Видимо что-то все-таки неправильно формируется ч-з function SignData(), только не могу понять что. Base64 верная, проверял в https://helpers.work/ru/encription/base64 Еще раз. Ответ выше был дан. На тестовой странице - присоединенная подпись. В коде на Delphi\Lazarus: SignData( True, si, so, null, ''); - что делает этот вызов? Не могу понять ход мысли :) На тестовой странице https://www.cryptopro.ru...ge/cades_bes_sample.html мы используем подпись и результат получается верный. Если мы пытаемся выполнить подпись аналогичной строки, той же самой подписью, что и используется для проверки подписи на тестовой странице, но из программы Delphi, то получаем другой (неверный) результат SignData( True, si, so, null, ''); как раз выполняет вызов функции подписи строки si и возвращает результат в so. null указывали, до того, как смогли получить сертификат. Сейчас весь год выглядит так:Код:
//Поиск сертификата по отпечатку
function GetCertificateOfStamp(thumbprint: string; var oCertificate: olevariant; var onErr: string): boolean;
const
CAPICOM_MY_STORE = 'MY';
CAPICOM_CERTIFICATE_FIND_SHA1_HASH = $00000000;
CAPICOM_CURRENT_USER_STORE = 2;
CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED = 2;
var
oStore, oCertificates: olevariant;
x: integer;
begin
onErr := '';
result := false;
try
oStore := CreateOleObject('CAdESCOM.Store');
oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED);
oCertificates := oStore.Certificates.Find(CAPICOM_CERTIFICATE_FIND_SHA1_HASH, widestring(thumbprint));
x := oCertificates.Count;
if x = 0 then
begin
onErr := 'Не найден сертификат с отпечатком: [' + thumbprint + ']';
exit;
end;
oCertificate := oCertificates.Item[1]; // oCertificates.Item(1);
result := true;
except
on e: exception do
begin
onErr := 'Не удалось получить доступ к сертификату с отпечатком: [' + thumbprint + '] ' + e.Message;
end;
end;
end;
Поиск проходит успешно, т.к. по отпечатку после поиска получаем верный серийный номер Ниже идет основная функция подписания, в параметры которой передаются True(bl_Detached), строка для подписания, ссылка на переменную для подписанной строки, Сертификат и его пароль. А на что влияет первый параметр bl_Detached ? Код:
//Функция подписания строки
function SignData(bl_Detached: boolean; S_in: WideString; var S_out: WideString ; g_Cert:OleVariant; g_Cert_Pass:string) :boolean;
const
CADESCOM_CADES_TYPE = 1; // Тип усовершенствованной подписи
CADESCOM_BASE64_TO_BINARY = 1;
var
v_Signer, v_SignedData : Variant;
s, Encoded: string;
Base64: TBase64Encoding;
begin
Result := False;
try
v_Signer := CreateOLEObject('CadesCOM.CPSigner');
v_Signer.Certificate := g_Cert;
//v_Signer.Certificate := GetSignerCertificate('0171ed4800daab20a54de41e513396cbae');
if g_Cert_Pass<>'' then
v_Signer.KeyPin := g_Cert_Pass;
v_Signer.Options := 1;// CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN := 1;
V_SignedData := CreateOLEObject('CAdESCOM.CadesSignedData');
v_SignedData.ContentEncoding := CADESCOM_BASE64_TO_BINARY;
Base64 := TBase64Encoding.Create(0);
//s := 'Some larger text that needs to be encoded in Base64 encoding';
//Base64 := TBase64Encoding.Create(10, '');
s_in := Base64.Encode(s_in);
//s_in := EncodeStringBase64(s_in);
v_SignedData.Content := s_in;
s_out := v_SignedData.SignCades(v_Signer, CADESCOM_CADES_TYPE, bl_Detached, 0);
Result := True;
finally
if not VarIsNull(v_Signer) then v_Signer := Unassigned;
if not VarIsNull(v_SignedData) then v_SignedData := Unassigned;
end;
end;
Затем вызов: Сначала ищем сертификат по отпечатку, после чего выполняем подписание строки Код:
procedure TForm1.btn1Click(Sender: TObject);
const
certStamp = 'тут указываем отпечаток сертификата';
var
si,so: WideString;
Cert: OleVariant;
errStr: string;
crtRes: boolean;
begin
si := edtString.Text; //Строка для подписания
crtRes := GetCertificateOfStamp(certStamp, Cert, errStr); //поиск по сертификату
if not crtRes then //Если сертификат не найден
begin
ShowMessage(errStr);
exit;
end;
ShowMessage('Серийный номер: ' + Cert.SerialNumber); //Печатаем серийный номер найденного по отпечатку сертификата
SignData(True, si, so, Cert, ''); //Подписываем строку si сертификатом Cert, пароль не указываем, т.к. его нет
mmo1.Text := so; //Результат подписания выводим по поле формы
end;
|