powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Lazarus CryptoAPI пара вопросов.
19 сообщений из 19, страница 1 из 1
Lazarus CryptoAPI пара вопросов.
    #38982118
angel_zar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Работа с CryptoAPI используя модуль JwaWinCrypt.
Имеются открытые ключи, из них надо получить информацию:
Срок действия
Кому выдан
Кем выдан
Улучшенный ключ

По первым 3-м пунктам все хорошо, а вот где найти информацию как достать значение "Улучшенный ключ", не могу.
Пример кода подкатом.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, JwaWinCrypt, LazUTF8, JwaWinSta, JwaWinBase, JwaWinType;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }


procedure TForm1.Button1Click(Sender: TObject);
var f: file;
    encCert: PByte;
    encCertLen: DWORD;
    //store: HCERTSTORE;
    context: PCCERT_CONTEXT;
    //n: PPCCERT_CONTEXT;
    encType: DWORD;
    nameBLOB: CERT_NAME_BLOB;
    size: DWORD;
    nameString: PChar;
    s:TStrings;
    FT:JwaWinBase.TFileTime;
begin
   s:=TStringList.Create;
   s.Clear;
   AssignFile(f, 'c:\temp\123.crt');
   reset(f, 1);
   encCertLen := FileSize(f);
   GetMem(encCert, encCertLen);
   BlockRead(f, encCert^, encCertLen);
   CloseFile(f);

   encType := PKCS_7_ASN_ENCODING or X509_ASN_ENCODING;
   context := CertCreateCertificateContext(encType, encCert, encCertLen);

   if context = nil then
   begin
   MessageDlg('Error creating certificate context', mtError, [mbOK], 0);
   exit;
   end;

   nameString := StrAlloc(512);

   FT.dwLowDateTime:=context^.pCertInfo^.NotBefore.dwLowDateTime;
   FT.dwHighDateTime:=context^.pCertInfo^.NotBefore.dwHighDateTime;

   s.Add('context^.pCertInfo^.NotBefore: '+DateTimeToStr(FileTime2DateTime(FT)));

   s.Add('==========================');


   FT.dwLowDateTime:=context^.pCertInfo^.NotAfter.dwLowDateTime;
   FT.dwHighDateTime:=context^.pCertInfo^.NotAfter.dwHighDateTime;

   s.Add('context^.pCertInfo^.NotAfter: '+DateTimeToStr(FileTime2DateTime(FT)));

   s.Add('==========================');



   s.Add('context^.pCertInfo^.Subject');
   nameBLOB := context^.pCertInfo^.Subject;
   size := CertNameToStr(encType, @nameBlob, CERT_X500_NAME_STR,nameString, 512);
   if size > 1 then
         s.Add(UTF8Encode(nameString))
      else
         s.Add('Error');

   s.Add('==========================');

   s.Add('context^.pCertInfo^.Issuer');
   nameBLOB := context^.pCertInfo^.Issuer;
   size := CertNameToStr(encType, @nameBlob, CERT_X500_NAME_STR, nameString, 512);
   if size > 1 then
         s.Add(UTF8Encode(nameString))
      else
         s.Add('Error');

   s.Add('==========================');

   //context^.hCertStore;

   {nameBLOB := context^.pCertInfo^.rgExtension;
   size := CertNameToStr(encType, @nameBlob, CERT_SIMPLE_NAME_STR,nameString, 512);
   if size > 1 then
         s.Add(UTF8Encode(nameString))
      else
         s.Add('Error');}

   //ShowMessage(s.Text);
   Memo1.Lines.Text:=s.Text;
   FreeMem(encCert, encCertLen);
   FreeAndNil(s);
end;

end.



Кто может подсказать, в какую сторону копать.
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38982232
MrCat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Речь про это ? (там key usage всё же, а не key)
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38982252
angel_zar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MrCatРечь про это ? (там key usage всё же, а не key)
Спасибо, это уже нашел тынц
Только не работает.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
CertGetEnhancedKeyUsage(m_pCertContext, 0, nil, usageLength);
  usage := PCERT_ENHKEY_USAGE(AllocMem(usageLength));
  try
    if (CertGetEnhancedKeyUsage(m_pCertContext, 0, usage, usageLength)) then
    begin
      if (usage.cUsageIdentifier = 0) then
      begin
        StringGrid1.Cells[index, certNum] := '<All>';
      end else begin
        for I := 0 to usage.cUsageIdentifier - 1 do
        begin
          usageStr := usage.rgpszUsageIdentifier;
        end;
      end;
    end else begin
      //TODO: It might not exist.
    end;
  finally
    FreeMem(usage, usageLength);
  end;



Смущает это: usageStr := usage.rgpszUsageIdentifier;
Пробовал по этому примеру, не могу вернуть коды. Количество правильное. А вот дальше что попало.
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38982303
MrCat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну, что в цикле всё время одно значение берётся, это ладно, описка. Но по идее, во втором параметре структуры должен быть массив указателей на строки. Т.е. что-то типа PPChar, а Вы с ним как с PChar обращаетесь. Плюс я бы ещё насчёт кодировки озаботился. Когда шерстятся теги ASN.1, то кроме указателя возвращается и кодировка данных, а тут - указатель на строку и всё. Это всегда ANSI-строка? Хотя, логично - OID - это три точки и 4 числа, ему UNICODE не нужен.
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38982314
angel_zar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MrCatНу, что в цикле всё время одно значение берётся, это ладно, описка. Но по идее, во втором параметре структуры должен быть массив указателей на строки. Т.е. что-то типа PPChar, а Вы с ним как с PChar обращаетесь. Плюс я бы ещё насчёт кодировки озаботился. Когда шерстятся теги ASN.1, то кроме указателя возвращается и кодировка данных, а тут - указатель на строку и всё. Это всегда ANSI-строка? Хотя, логично - OID - это три точки и 4 числа, ему UNICODE не нужен.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
   If (CertGetEnhancedKeyUsage(context, 0, nil, size)) THEN
   begin
     Usage:=PCERT_ENHKEY_USAGE(AllocMem(size));
   end;
   If (CertGetEnhancedKeyUsage(context, 0, Usage, size)) THEN
      s.Add(FloatToStr(Usage^.cUsageIdentifier));
      for n := 1 to Usage^.cUsageIdentifier do
        begin
          s.Add(UTF8Encode(Usage[n].rgpszUsageIdentifier));
        end;


Сам до такого дошел, но массив не полный, на ключе который проверяю Usage^.cUsageIdentifier=12, а на 5 ке цикл вываливается :(.
Про это можно по подробней? Просто там был кусок кода из того что я нашел в сети для примера, пытаюсь под себя прикрутить.
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38982320
angel_zar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Плюс я бы ещё насчёт кодировки озаботился. Когда шерстятся теги ASN.1, то кроме указателя возвращается и кодировка данных, а тут - указатель на строку и всё. Это всегда ANSI-строка?
Вот про это можно по подробней.
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38982343
MrCat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я про CERT_RDN_ATTR.dwValueType , и сразу было понятно что делать с Value.
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38982357
MrCat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я бы написал так. Не проверял, просто продемонстрировать идею. Насчёт кодировки, в которой возвращается OID - не в курсе, возможно, действительно надо ещё decode from UTF8
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
var 
  Count: Integer;
  pStrs: PPChar;
  pStr: PChar;
...
  if CertGetEnhancedKeyUsage(context, 0, Usage, size) then
  begin
     Count := Usage^.cUsageIdentifier;
     s.Add(IntToStr(Count));
 
     pStrs := Usage.rgpszUsageIdentifier;
     for n := 0 to Pred(Count) do
     begin
       pStr := pStrs^[n];
       s.Add(StrPas(pStr));
     end;
  end;
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38982478
Ghost Writer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
angel_zar,

я когда-то тут подсказывал http://www.cryptopro.ru/forum2/default.aspx?g=posts&m=15919#post15919
попробуйте
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38983679
angel_zar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо, получилось так.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
If (CertGetEnhancedKeyUsage(context, 0, nil, size)) THEN
   begin
     Usage:=PCERT_ENHKEY_USAGE(AllocMem(size));
   end;
   If (CertGetEnhancedKeyUsage(context, 0, Usage, size)) THEN
      s.Add('Count:'+FloatToStr(Usage^.cUsageIdentifier));
      for n := 0 to Usage^.cUsageIdentifier-1 do
        begin
         UsageT:=(PCharArr(Usage^.rgpszUsageIdentifier)[n])[0];
         s.Add(String(UsageT));
        end;       


Сейчас тестируем, на разных ключах.
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38984378
sql2012
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
angel_zarВсем спасибо, получилось так.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
If (CertGetEnhancedKeyUsage(context, 0, nil, size)) THEN
   begin
     Usage:=PCERT_ENHKEY_USAGE(AllocMem(size));
   end;
   If (CertGetEnhancedKeyUsage(context, 0, Usage, size)) THEN
      s.Add('Count:'+FloatToStr(Usage^.cUsageIdentifier));
      for n := 0 to Usage^.cUsageIdentifier-1 do
        begin
         UsageT:=(PCharArr(Usage^.rgpszUsageIdentifier)[n])[0];
         s.Add(String(UsageT));
        end;       


Сейчас тестируем, на разных ключах.

Тестируешь, потому что не уверен в правильности расстановки begin\end или в криптографических функциях?
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38984828
angel_zar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot sql2012]angel_zarТестируешь, потому что не уверен в правильности расстановки begin\end или в криптографических функциях?
Что бы быть уверенным, что будет работать правильно, а так тут черновой вариант, просто разобраться, как это работает.
Весь код будет обернут в класс, с обработками ошибок.
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38985009
sql2012
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot angel_zar]sql2012пропущено...

Что бы быть уверенным, что будет работать правильно, а так тут черновой вариант, просто разобраться, как это работает.
Весь код будет обернут в класс, с обработками ошибок.

Когда CertGetEnhancedKeyUsage вернет false, будешь к Usage=nil обращаться и получишь AV...
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #38985346
angel_zar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sql2012Когда CertGetEnhancedKeyUsage вернет false, будешь к Usage=nil обращаться и получишь AV...
Я это прекрасно вижу, это фактически копи-паст, с некоторыми изменениями.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Lazarus CryptoAPI пара вопросов.
    #39813189
SQL-Talker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
angel_zarВсем спасибо, получилось так.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
If (CertGetEnhancedKeyUsage(context, 0, nil, size)) THEN
   begin
     Usage:=PCERT_ENHKEY_USAGE(AllocMem(size));
   end;
   If (CertGetEnhancedKeyUsage(context, 0, Usage, size)) THEN
      s.Add('Count:'+FloatToStr(Usage^.cUsageIdentifier));
      for n := 0 to Usage^.cUsageIdentifier-1 do
        begin
         UsageT:=(PCharArr(Usage^.rgpszUsageIdentifier)[n])[0];
         s.Add(String(UsageT));
        end;       


Сейчас тестируем, на разных ключах.

Привет, народ.

Мне нужно выяснить содержится ли в параметре "Улучшенный ключ" OID "Подписывание документа" - "1.3.6.1.4.1.311.10.3.12"
Насколько я понял, в процитированном коде, в
Код: pascal
1.
PCharArr(Usage^.rgpszUsageIdentifier)[n]

как раз и должен содержаться этот OID,
но у меня там получается строка типа автор#$2E31#$2E33#$2E36#$2E31#$2E34#$2E31'ㄳ'#$2E31'〱㌮'#$312E'2'#$2E31#$2E33#$2E36#$2E31#$2E35#$2E35#$2E37#$2E33'2' - по-видимому символы из юникода
а
Код: pascal
1.
Usage^.rgpszUsageIdentifier

содержит автор'а9›'#2'ш9›'#2'1.3.6.1.4.1.311.10.3.12'
хотя там должно быть два OID-а

Подскажите, как мне правильно получить OID-ы там содержащиеся?
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #39813192
SQL-Talker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И да, использовал определения типа PCharArr (с форума КриптоПро):
Код: pascal
1.
2.
3.
type
  PCharArr = ^TCharArr;
  TCharArr = array[0..0] of PChar;
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #39813243
Ghost Writer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL-TalkerИ да, использовал определения типа PCharArr (с форума КриптоПро):В какой среде пишите? тот код я писал под Delphi 7. В лазарусе всё также работает с маленькой поправкой:
Код: pascal
1.
PCharArr(pbEnhanced^.rgpszUsageIdentifier)^[I]
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #39813249
Ghost Writer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В Delphi 10.2 (Токио вроде зовётся)
Код: pascal
1.
2.
3.
type
  PCharArr = ^TCharArr;
  TCharArr = array[0..0] of PAnsiChar;
...
Рейтинг: 0 / 0
Lazarus CryptoAPI пара вопросов.
    #39813384
SQL-Talker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ghost Writer,

Все заработало, спасибо!
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Lazarus CryptoAPI пара вопросов.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]