Статус: Активный участник
Группы: Участники
Зарегистрирован: 20.06.2012(UTC) Сообщений: 30 Откуда: Москва Сказал «Спасибо»: 4 раз Поблагодарили: 4 раз в 2 постах
|
Андрей * написал:в общем: твой код целиком перенес к себе - и ЭЦП перестала быть валидной после создания ... Да! Ура! Наконец-то получился работающий код! В сухом остатке правильно работающий модуль: Код:
unit MainUnit;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.Oleauto,
CAPICOMUtilitiesUnit, System.Types, IdCoderMIME, IdGlobal,
CAPICOM_TLB,
ActiveX,
System.Win.ComObj;
type
//TByteArray = array of Byte;
TMainForm = class(TForm)
GroupBoxSignedFile: TGroupBox;
GroupBoxSignFile: TGroupBox;
EditSignedFile: TEdit;
EditSignFile: TEdit;
BitBtn3: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
// **********************************************cFXML
// Создание цифровой подписи
procedure TMainForm.BitBtn3Click(Sender: TObject);
var
filStream: TFileStream;
Buffer: WideString;
oStore: CAPICOM_TLB.IStore;
oSignedData: CAPICOM_TLB.ISignedData;
oSigner: CAPICOM_TLB.ISigner2;
oCertificates: CAPICOM_TLB.ICertificates2;
oCer1: CAPICOM_TLB.ICertificates;
oAttribute: CAPICOM_TLB.IAttribute;
begin
// Чтение файла
filStream := TFileStream.Create(EditSignedFile.Text, fmOpenRead or fmShareDenyWrite);
try
Pointer(Buffer) := SysAllocStringByteLen(nil, filStream.Size);
filStream.ReadBuffer(Pointer(Buffer)^, filStream.Size);
finally
FreeAndNil(filStream);
end;
// Создать COM-объекты
try
oStore := CoStore.Create;
oSignedData := CoSignedData.Create;
//oSigner := CoSigner.Create;
oSigner := CreateComObject(CLASS_Signer) as CAPICOM_TLB.ISigner2;
// Обратиться к контейнеру
oStore.Open(CAPICOM_CURRENT_USER_STORE,'My', CAPICOM_STORE_OPEN_READ_ONLY);
// Нужно поставить галку "Включить время создания подписи"
oAttribute := CoAttribute.Create;
oAttribute.Name := CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME;
oAttribute.Value := now; // в UTC нужно...
oSigner.AuthenticatedAttributes.Add(oAttribute);
except
on oErr: Exception do
begin
ShowMessage('Для подписи запроса электронно-цифровой подписью необходимо наличие установленного компонента Microsoft CAPICOM на вашей рабочей станции.'+chr(13)+
'Пожалуйста, обратитесь к системному администратору.'+Chr(13)+
Trim(oErr.Message));
exit;
end;
end;
// Содержимое
oSignedData.Content := Buffer;
// Выбрать сертификат
try
oCertificates := oStore.Certificates;
//oCertificates := ICertificates2(IDisPatch(oStore.Certificates));
oCer1 := oCertificates.Select('Выбор сертификата', 'Пожалуйста, выберите сертификат для подписи.', FALSE);
oSigner.Certificate := CAPICOM_TLB.ICertificate2(IDisPatch(oCer1.Item[1]));
except
on oErr: Exception do
begin
ShowMessage('Сертификат не найден. Пожалуйста, обратитесь к системному администратору.!' + Chr(13) +
Trim(oErr.Message));
Exit;
end;
end;
// Создание ЭЦП
Buffer := oSignedData.Sign(oSigner, TRUE, CAPICOM_ENCODE_BINARY);
// Запись ЭЦП в файл:
try
filStream := TFileStream.Create(EditSignFile.Text, fmCreate );
filStream.WriteBuffer(Pointer(Buffer)^, SysStringByteLen(PWideChar(Buffer)));
finally
filStream.Free;
end;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
CoInitialize(nil);
end;
end.
Большое спасибо за помощь! Часто работа с криптографией похожа на игру в черный ящик Вложение(я): capicom.dll (496kb) загружен 197 раз(а). CAPICOM_TLB.pas (140kb) загружен 221 раз(а).У Вас нет прав для просмотра или загрузки вложений. Попробуйте зарегистрироваться.
|
2 пользователей поблагодарили Zester за этот пост.
|
|