![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
|
Доброго времени суток. Пишу программу контроля сроков действия сертификатов ЭЦП: то есть имея дату начала и дату конца сертификата, мы можем вычислить, сколько времени осталось до его истечения. Выводить из базы данных владельцев с возможностью отправки уведомления на e-mail, указанный в сертификате. Так вот мне нужно научиться самому и научить свою программу вытягивать нужные мне данные из сертификата при загрузке. (сертификаты в cer-кодировке). Нашел листинг прогаммного получения серийного номера из серта, но вот понять что к чему там не могу.
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
OpenDialog1: TOpenDialog;
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 CertCreateCertificateContext(dwCertEncodingType: DWORD;
pbCertEncoded: PBYTE; cbCertEncoded: DWORD): PCCERT_CONTEXT; stdcall
external 'crypt32.dll';
const
X509_ASN_ENCODING = $00000001;
PKCS_7_ASN_ENCODING = $00010000;
var
Form1: TForm1;
implementation
{$R *.dfm}
function ByteArrayToStr(pbData: PByte; cbData: DWORD): String;
var
I, J: Integer;
S: String;
begin
Result := '';
if not Assigned(pbData) or (cbData <= 0) then
Exit;
for I := 0 to cbData - 1 do
begin
J := PByteArray(pbData)^[i];
S := IntToHex(J, 2);
if (I > 0) and (I and 1 = 0) then
S := S + ' ';
Result := S + Result;
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 or
PKCS_7_ASN_ENCODING, M.Memory, M.Size);
if Assigned(Context) then
try
ShowMessage(GetSerialNumber(Context));
finally
if not CertFreeCertificateContext(Context) then
ShowMessage(SysErrorMessage(GetLastError));
end;
finally
M.Free;
end;
end;
end;
end.Прошу знающих людей помочь в данном вопросе. Прокомментировать ключевые строки. Что где когда берется и как это реализовывается. Если кто может написать процедуру по моему заданию, будет замечательно. В долгу не останусь. Обсуждение суммы в лс или по асе:352587850 Последний раз редактировалось Admin, 23.05.2011 в 09:31. |
|
#2
|
||||
|
||||
|
По-моему данные о сроках в самой ЭЦП не вшиты. а сроки определяются уже самой АС, в которой генерятся и регаются ЭЦП. и в которой соответственно есть контроль времени..
|
|
#3
|
||||
|
||||
|
Нет. В сертификате открытого ключа есть поля с какого по какое он действителен. Для пользователей выдаются сертификаты ровно на год, день в день. То есть имея сертификат и системное время на компе, мы можем определить через сколько дней он истечет. Соответственно при загрузке данного серта в карточку моей организации, я не хочу грузить полностью все что прописано в сертификате, а только дату конца его, e-mail и серийный номер. Что б за 30 и менее дней до его истечения, я мог сформировать письмо в адрес организации и отправить его уведомлением на e-mail, указанный в серте.
Вот пример сертификата ЭЦП: Sert.JPG |
|
#4
|
||||
|
||||
|
да, действительно...
Просто я работал с такой, АС в которой имелась возможность продлевать срок ЭЦП без ее наличия.. поэтому не счел наличие соответствующих полей действительным.. вот почитай может окажется полезным можешь кинуть паблик, тоже поразбираюсь... Последний раз редактировалось Pilot_Red, 23.05.2011 в 18:06. |
|
#5
|
||||
|
||||
|
Цитата:
Спасибо за ссылку, но это мне все известно. ежегодно сдаем экз. на работе по этой бурде. Во вложении архив с моей программкой(это не то,что я пишу, просто на скорую руку накидал форму для проверки работоспособности)- мне нужно только вытягивать поля: Серномер, E-mail и Дату окончания. Там же 2 серта: один экспортирован из ключа в X509 Base64- кодировке (и него прога даже серийный номер не может вытащить), второй X509 DER- кодировке(его грузит относительно нормально) GetDataSert.rar |
|
#6
|
||||
|
||||
|
дату выдрал. Завтра если время будет попробую мыло вытянуть...
Последний раз редактировалось Pilot_Red, 14.06.2012 в 22:25. |
|
#7
|
||||
|
||||
|
Спс за поддержку. Дома поковыряюсь в проге, может и у меня что получится. Но если сделаешь вытянешь мыло, буду признателен. Мне из серта больше ничего и не надо.
|
| Этот пользователь сказал Спасибо Vayrus за это полезное сообщение: | ||
login (01.12.2016)
| ||
|
#10
|
||||
|
||||
|
Рад что помогло
![]() ЗЫ Ну можешь мне репутацию повысить, этого достаточно ![]() |
|
#11
|
||||
|
||||
|
Код было бы неплохо "причесать".
|
|
#12
|
||||
|
||||
|
Писалось, как говориться, на коленке и на быструю руку с портативной Делфи, да и вообще, причесывает пусть тот кому нужно, всю тяжелую работу я уже сделал)
|
|
#13
|
||||
|
||||
|
причешу в процессе. Сейчас надо только сделать что бы не в Memo это все кидалось, а в DBGrid при загрузке файла сертификата в базу.
|