- Регистрация
- 9 Май 2015
- Сообщения
- 1,551
- Баллы
- 155
Программа предназначена для контроля сроков действия цифровых сертификатов и извлечения данных владельцев сертификатов из файлов формата *.cer. Она выполняет следующие функции:
1. Вычисление оставшегося времени до истечения срока действия сертификата:
Такой подход позволяет пользователю следить за сроками действия цифровых сертификатов и получать информацию о владельцах для дальнейших действий.

[HIDE]
[/HIDE]
1. Вычисление оставшегося времени до истечения срока действия сертификата:
- Программа загружает сертификат в формате .cer через диалоговое окно.
- Извлекает дату начала и окончания действия сертификата.
- Вычисляет, сколько времени осталось до истечения сертификата, отображая это в пользовательском интерфейсе.
- Программа получает из сертификата серию уникальных данных, таких как серийный номер сертификата и дата его окончания.
- Извлекает email-адрес владельца сертификата из поля Subject (если он присутствует).
- Отображает эти данные в текстовых полях интерфейса.
- Программа предоставляет возможность отправить уведомление на электронную почту владельца сертификата, если такая информация указана в сертификате.
- Для отправки уведомлений можно реализовать дополнительный функционал через SMTP-клиент или другие способы.
- Загрузка сертификата: Осуществляется через стандартное окно выбора файла.
- Парсинг сертификата: Используются стандартные криптографические библиотеки Windows (crypt32.dll), которые позволяют работать с цифровыми сертификатами.
- Отображение данных: Извлекаются и отображаются:
- Серийный номер сертификата.
- Дата истечения срока действия.
- Электронный адрес владельца (если он указан).
- В интерфейсе формы имеется кнопка для выбора файла сертификата и три текстовых поля для отображения:
- Серийный номер сертификата (Edit1).
- Дата истечения срока действия сертификата (Edit2).
- Email владельца сертификата (Edit3).
- В коде программы используется несколько ключевых функций:
- CertCreateCertificateContext: Создаёт контекст сертификата для дальнейшей работы с его данными.
- CertNameToStrA: Извлекает строковое представление имени субъекта сертификата, что позволяет найти email.
- FileTimeToDateTimeStr: Преобразует дату окончания срока действия сертификата из формата FILETIME в строку.
- ByteArrayToStr: Преобразует байтовый массив в строковое представление для серийного номера сертификата.
- Пользователь выбирает файл сертификата в формате .cer.
- Программа извлекает данные из сертификата:
- Серийный номер.
- Дату окончания срока действия.
- Email владельца (если он есть).
- Отображает эти данные в соответствующих полях.
- (Опционально) Программа может быть расширена для отправки уведомлений на email владельца.
- Программа работает с сертификатами, закодированными в формате X.509.
- Для корректной работы нужно использовать библиотеку crypt32.dll, которая является частью Windows и предоставляет API для работы с сертификатами.
- Возможность отправки уведомлений по электронной почте требует настройки SMTP-клиента, что можно добавить в будущем.
Такой подход позволяет пользователю следить за сроками действия цифровых сертификатов и получать информацию о владельцах для дальнейших действий.

[HIDE]
Код:
unit GetDataSert;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DateUtils;
type
TForm1 = class(TForm)
Button1: TButton;
OpenDialog1: TOpenDialog;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
CRYPTOAPI_BLOB = packed record
cbData: DWORD;
pbData: PByte;
end;
CRYPT_INTEGER_BLOB = CRYPTOAPI_BLOB;
CRYPT_OBJID_BLOB = CRYPTOAPI_BLOB;
CERT_NAME_BLOB = CRYPTOAPI_BLOB;
CRYPT_ALGORITHM_IDENTIFIER = packed record
pszObjId: LPSTR;
Parameters: CRYPT_OBJID_BLOB;
end;
CRYPT_BIT_BLOB = packed record
cbData: DWORD;
pbData: PByte;
cUnusedBits: DWORD;
end;
CERT_PUBLIC_KEY_INFO = packed record
Algorithm: CRYPT_ALGORITHM_IDENTIFIER;
PublicKey: CRYPT_BIT_BLOB;
end;
CERT_EXTENSION = packed record
pszObjId: LPSTR;
fCritical: BOOL;
Value: CRYPT_OBJID_BLOB;
end;
PCERT_EXTENSION = ^CERT_EXTENSION;
TARR_CERT_EXTENSION = PCERT_EXTENSION;
CERT_INFO = packed record
dwVersion: DWORD;
SerialNumber: CRYPT_INTEGER_BLOB;
SignatureAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
Issuer: CERT_NAME_BLOB;
NotBefore: FILETIME;
NotAfter: FILETIME;
Subject: CERT_NAME_BLOB;
SubjectPublicKeyInfo: CERT_PUBLIC_KEY_INFO;
IssuerUniqueId: CRYPT_BIT_BLOB;
SubjectUniqueId: CRYPT_BIT_BLOB;
cExtension: DWORD;
rgExtension: TARR_CERT_EXTENSION;
end;
PCERT_INFO = ^CERT_INFO;
HCERTSTORE = Pointer;
HCRYPTPROV = ULONG;
CERT_CONTEXT = packed record
dwCertEncodingType: DWORD;
pbCertEncoded: PByte;
cbCertEncoded: DWORD;
pCertInfo: PCERT_INFO;
HCERTSTORE: HCERTSTORE;
end;
PCERT_CONTEXT = ^CERT_CONTEXT;
PCCERT_CONTEXT = ^CERT_CONTEXT;
function CertFreeCertificateContext(pCertContext: PCCERT_CONTEXT): BOOL;
stdcall external 'crypt32.dll';
function CertNameToStrA(dwCertEncodingType: DWORD;
pName: PCERT_NAME_BLOB; dwStrType: DWORD;
psz: PAnsiChar; csz: DWORD): DWORD; stdcall; external 'crypt32.dll';
function CertCreateCertificateContext(dwCertEncodingType: DWORD;
pbCertEncoded: PByte; cbCertEncoded: DWORD): PCCERT_CONTEXT;
stdcall external 'crypt32.dll';
const
X509_ASN_ENCODING = $00000001;
PKCS_7_ASN_ENCODING = $00010000;
CERT_X500_NAME_STR = 3;
var
Form1: TForm1;
implementation
{$R *.dfm}
function ByteArrayToStr(pbData: PByte; cbData: DWORD): String;
var
I: Integer;
begin
Result := '';
if not Assigned(pbData) or (cbData = 0) then
Exit;
for I := cbData - 1 downto 0 do
Result := Result + IntToHex(pbData[I], 2);
end;
function FileTimeToDateTimeStr(ft: FILETIME): string;
var
lft: TFileTime;
st: TSystemTime;
dt: TDateTime;
begin
if FileTimeToLocalFileTime(ft, lft) and FileTimeToSystemTime(lft, st) then
begin
dt := SystemTimeToDateTime(st);
Result := DateTimeToStr(dt);
end
else
Result := 'Ошибка даты';
end;
function GetEmailFromSubject(CertContext: PCCERT_CONTEXT): string;
var
Buffer: array[0..1023] of AnsiChar;
SubjectStr: string;
PosE: Integer;
begin
Result := '';
if CertContext = nil then Exit;
if CertNameToStrA(X509_ASN_ENCODING, @CertContext.pCertInfo.Subject,
CERT_X500_NAME_STR, Buffer, Length(Buffer)) > 0 then
begin
SubjectStr := string(Buffer);
PosE := Pos('E=', SubjectStr);
if PosE > 0 then
begin
Result := Copy(SubjectStr, PosE + 2, MaxInt);
if Pos(',', Result) > 0 then
Result := Copy(Result, 1, Pos(',', Result) - 1);
end;
end;
end;
function GetSerialNumber(CertInfo: PCCERT_CONTEXT): String;
begin
Result := ByteArrayToStr(CertInfo.pCertInfo.SerialNumber.pbData,
CertInfo.pCertInfo.SerialNumber.cbData);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Context: PCCERT_CONTEXT;
M: TMemoryStream;
begin
if OpenDialog1.Execute then
begin
M := TMemoryStream.Create;
try
M.LoadFromFile(OpenDialog1.FileName);
Context := CertCreateCertificateContext(X509_ASN_ENCODING,
M.Memory, M.Size);
if Assigned(Context) then
try
Edit1.Text := GetSerialNumber(Context);
Edit2.Text := FileTimeToDateTimeStr(Context.pCertInfo^.NotAfter);
Edit3.Text := GetEmailFromSubject(Context);
finally
CertFreeCertificateContext(Context);
end
else
ShowMessage('Ошибка создания контекста: ' +
SysErrorMessage(GetLastError));
finally
M.Free;
end;
end;
end;
end.