• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Delphi Программно получить данные из сертификата

Sascha

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

  • Программа загружает сертификат в формате .cer через диалоговое окно.
  • Извлекает дату начала и окончания действия сертификата.
  • Вычисляет, сколько времени осталось до истечения сертификата, отображая это в пользовательском интерфейсе.
2. Извлечение данных владельца сертификата:

  • Программа получает из сертификата серию уникальных данных, таких как серийный номер сертификата и дата его окончания.
  • Извлекает email-адрес владельца сертификата из поля Subject (если он присутствует).
  • Отображает эти данные в текстовых полях интерфейса.
3. Отправка уведомлений:

  • Программа предоставляет возможность отправить уведомление на электронную почту владельца сертификата, если такая информация указана в сертификате.
  • Для отправки уведомлений можно реализовать дополнительный функционал через SMTP-клиент или другие способы.
Основные функции программы:

  • Загрузка сертификата: Осуществляется через стандартное окно выбора файла.
  • Парсинг сертификата: Используются стандартные криптографические библиотеки Windows (crypt32.dll), которые позволяют работать с цифровыми сертификатами.
  • Отображение данных: Извлекаются и отображаются:
    • Серийный номер сертификата.
    • Дата истечения срока действия.
    • Электронный адрес владельца (если он указан).
Подробное описание кода:

  • В интерфейсе формы имеется кнопка для выбора файла сертификата и три текстовых поля для отображения:
    • Серийный номер сертификата (Edit1).
    • Дата истечения срока действия сертификата (Edit2).
    • Email владельца сертификата (Edit3).
  • В коде программы используется несколько ключевых функций:
    • CertCreateCertificateContext: Создаёт контекст сертификата для дальнейшей работы с его данными.
    • CertNameToStrA: Извлекает строковое представление имени субъекта сертификата, что позволяет найти email.
    • FileTimeToDateTimeStr: Преобразует дату окончания срока действия сертификата из формата FILETIME в строку.
    • ByteArrayToStr: Преобразует байтовый массив в строковое представление для серийного номера сертификата.
Пример работы программы:

  1. Пользователь выбирает файл сертификата в формате .cer.
  2. Программа извлекает данные из сертификата:
    • Серийный номер.
    • Дату окончания срока действия.
    • Email владельца (если он есть).
  3. Отображает эти данные в соответствующих полях.
  4. (Опционально) Программа может быть расширена для отправки уведомлений на email владельца.
Важные моменты:

  • Программа работает с сертификатами, закодированными в формате X.509.
  • Для корректной работы нужно использовать библиотеку crypt32.dll, которая является частью Windows и предоставляет API для работы с сертификатами.
  • Возможность отправки уведомлений по электронной почте требует настройки SMTP-клиента, что можно добавить в будущем.

Такой подход позволяет пользователю следить за сроками действия цифровых сертификатов и получать информацию о владельцах для дальнейших действий.

1746289324017.png


[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.
[/HIDE]
 
Вверх Снизу