2.4.3. Криптографические методы

2.4.3.1. Описание функций

  1. Создание подписи сообщения.
function SignMessage(Data: String; CertID: String; out Result: Blob): Boolean;
  1. Проверка подписи сообщения.
function VerifyMessage(Data: String; Sign: Blob; out Log: String): Boolean;
  1. Добавление списка отозванных сертификатов в хранилище “Доверенные корневые центры сертификации”.
function AddCRLToRoot(Crl: Blob): Boolean;
  1. Получение даты подписи. По умолчанию при подписании данных ставится дата UTC.
function GetDateFromSign(Sign: Blob; out Date: TDateTime): Boolean;
  1. Проверка актуальности списка отозванных сертификатов. Возвращает: False - если есть список и дата удовлетворяет, True - нет списка или нужно обновить список отозванных сертификатов.
function IsCRLOutOfDate(Sign: Blob): Boolean;
  1. Загрузка списка отозванных сертификатов.
function LoadCRLByURL(Url: String; out Crl: Blob): Boolean;
  1. Обновление списка отозванных сертификатов. Если флаг Force установлен в False, то функция проверяет действительность списка и обновляет его только при необходимости, иначе обновляет без проверки.
function RefreshCRL(Sign: Blob; Log: String; Force: Boolean): Boolean;
  1. Проверка наличия сертификата из подписи в списках отозванных сертификатов.
function VerifyCertFromSignInCRL(Sign: Blob): Boolean;
  1. Проверка наличия сертификата в списках отозванных сертификатов.
function VerifyCertInCRL(CertID: String): Boolean;
  1. Получение отпечатка сертификата в виде строки шестнадцатеричных цифр без пробелов.
function GetThumbprintHexStringByCertID(CertID: String): string;
  1. Получение сертификата в виде массива байт.
function GetRawDataByCertID(CertID: String): Blob;

2.4.3.2. Пример

var
   MyMessage, Sign, spLog, crl: string;
   d: DateTime;
 begin
   MyMessage := 'Сообщение, которое нужно подписать';
   // Откроем диалоговое окно и выберем сертификат для подписи
   CertID := Cryptor.OpenCertificateDlg;
   if VarIsNull(CertID) then
   begin
     ShowMessage('Сертификат не выбран');
     Exit;
   end;

   // Проверим цепочку сертификатов
   if Cryptor.VerifyCertificate(CertID, spLog) <> 0 then
   begin
     // Сертификат не прошёл проверку
     ShowMessage(spLog);
     Exit;
   end;

   // По желанию можно обновить список отозванных сертификатов вручную
   if not Cryptor.LoadCRLByURL('http://test.ru/my.crl', crl) then
   begin
     ShowMessage('Неудалось загрузить список отозванных сертификатов');
     Exit;
   end;

   // Попытка установки списка отозванных сертификатов
   if not Cryptor.AddCRLToRoot(crl) then
     ShowMessage('Не удалось установить список отозванных сертификатов. Возможно он уже установлен');

   // Проверка в списках отозванных сертификатов
   if not Cryptor.VerifyCertInCRL(CertID) then
   begin
     ShowMessage('Сертификат в списке отозванных');
     Exit;
   end;

   // Подписание сообщения
   if not Cryptor.SignMessage(MyMessage, CertID, Sign) then
   begin
     ShowMessage('Ошибка при подписании.');
     Exit;
   end;

   // Получение даты подписания
   if Cryptor.GetDateFromSign(Sign, d) then
     ShowMessage('Сообщение подписано ' + DateTimeToStr(d))
   else
     ShowMessage('Не удалось получить дату из подписи');

   // Проверка сообщения
   // Обновим список отозванных сертификатов, если это требуется. IsCRLOutOfDate также используется
   // в RefreshCRL, если флаг Force = False
   if Cryptor.IsCRLOutOfDate(Sign) then
     if not Cryptor.RefreshCRL(Sign, spLog, true) then
     begin
       ShowMessage('Неудалось обновить списки отозванных');
       Exit;
     end;

   // Проверка сертификата, которым было подписано сообщение, на отозванность
   // происходит при проверке сообщения, но данную проверку можно сделать отдельно
   if not Cryptor.VerifyCertFromSignInCRL(Sign) then
   begin
     ShowMessage('Сертификат, которым было подписано сообщение в списке отозванных');
     Exit;
   end;

   if not Cryptor.VerifyMessage(MyMessage, Sign, spLog) then
   begin
     // Ошибка
     ShowMessage(spLog);
     Exit;
   end else
     ShowMessage('Подпись подтверждена.');

   // Получение отпечатка сертификата
   CertID := Cryptor.OpenCertificateDlg;
   thumbPrint := Cryptor.GetThumbprintHexStringByCertID(CertID);
   ShowMessage('Отпечаток выбранного сертификата = ' + thumbPrint);

   // Получение сертификата в виде массива байт
   CertID := Cryptor.OpenCertificateDlg;
   rawData := Cryptor.GetRawDataByCertID(CertID);
   // красивый вывод на экран, чотбы все нормально уместилось
   strRawData := 'RawData = ' + #13#10;
   for i := 0 to length(rawData)-1 do
   begin
     strRawData := strRawData + IntToStr(rawData[i]) + ', ';
     if (i mod 20 = 0) and (i <> 0) then
       strRawData := strRawData + #13#10;
   end;
   ShowMessage(strRawData);

 end;