|
|
Регистрация | << Правила форума >> | 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
|
||||
|
||||
Код было бы неплохо "причесать".
— Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#12
|
||||
|
||||
Писалось, как говориться, на коленке и на быструю руку с портативной Делфи, да и вообще, причесывает пусть тот кому нужно, всю тяжелую работу я уже сделал)
|
#13
|
||||
|
||||
причешу в процессе. Сейчас надо только сделать что бы не в Memo это все кидалось, а в DBGrid при загрузке файла сертификата в базу.
|