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

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

  1. Создание подписи сообщения.
function SignMessage(data: String; certID: String; out rslt: String): Boolean;
  1. Проверка подписи сообщения. Изменён 3й параметр. Теперь возвращается лог проверки, а не идентификатор сертификата.
function VerifyMessage(data: String; sign: String; out spLog: String): Boolean;
  1. Добавление списка отозванных в хранилище (по умолчанию в Доверительные корневые центры сертификации)
function AddCRLToRoot(<br>crl: String<br>): Boolean;
  1. Получение даты подписи. По умолчанию при подписании данных ставится дата UTC
function GetDateFromSign(sign: String; out date: TDateTime): Boolean;
  1. Проверка по дате подписи актуальность списков CRL. Возвращает: True - если есть список и дата удовлетворяет, False - нет списка или нужно обновить CRL
function IsCRLOutOfDate(sign: String): Boolean;
  1. Функция загружает по заданному адресу CRL список.
function LoadCRLByURL(url: String; out crl: String): Boolean;
  1. Обновляет списки отозванных сертификатов и обновляет их по необходимости. Если установлен флаг bpForce в False, то функция проверяет действие CRL списков и обновляет только по необходимости. Иначе обновляет в любом случае.
function RefreshCRL(sign: String; spLog: String; bpForce: String): Boolean;
  1. Проверяет наличие сертификата из подписи в списках отозванных.
function VerifyCertFromSignInCRL(sign: String): Boolean;
  1. Проверяет наличие сертификата в списках отозванных по идентификатору сертификата.
function VerifyCertInCRL(CertID: String): Boolean;
  1. Отпечаток сертификата в виде строки шестнадцитиричных цифр без пробелов.
function GetThumbprintHexStringByCertID(CertID: String): string;
  1. Массив данных сертификата. Возвращается в воде массива байт.
function GetRawDataByCertID(CertID: String): variant array of byte;

3.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 not Cryptor.VerifyCertificate(CertID, spLog) then
   begin
     // Сертификат не прошёл проверку
     ShowMessage(spLog);
     Exit;
   end;

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

   // Попытка установки CRL
   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('Не удалось получить дату из подписи');

   // Проверка сообщения
   // Обновим CRL, если это требуется. IsCRLOutOfDate также используется
   // в RefreshCRL, если флаг bpForce = 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;