DICAS

Visite a biblioteca de dicas da comunidade.

Saiba mais

ARTIGOS

Abordagens detalhadas sobre assuntos diversos.

Saiba mais

INICIANTES

Aprenda a programar de um modo simples e fácil.

Saiba mais

DOWNLOADS

Acesse os materiais exclusivos aos membros.

Saiba mais
voltar

PARA QUEM GOSTA DE DELPHI

Como obter a validade de um certificado digital A1 utilizando OpenSSL?

Muitas vezes precisamos saber a validade de um certificado digital,
o modo mais comum é instalar o mesmo e utilizar as funções da capicom.dll.

Há casos porém, que não podemos instalar o certificado, ou, que não
podemos fazer uso da capicom.dll.

Para resolver este problema, podemos ler a data de validade diretamente do
certificado através da OpenSSL.

A função em si é complexa, mas o seu uso é muito simples.

Seu uso é aplicado somente para certificados do tipo A1.

Para utilizar a função é necessário também que o arquivo openssl.exe
esteja junto com o seu executável.
Você pode baixar da internet pelo site http://indy.fulgan.com/SSL/,
ou se você utilizar o ACBr, eles disponibilizam este exe junto com os
demais arquivos.

É necessário estar de SysUtils, ShellAPI e Windows na seção uses,
em versões unicode declare System.SysUtils, Winapi.ShellAPI e Winapi.Windows.

Abaixo segue o código fonte da função:

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
function ValidadeCertificado(wCertificado,
  wSenha: string): string;
  function Months(wM: string): string;
  begin
    wM := UpperCase(wM);
    if wM = 'JAN' then
      Result := '1'
    else if wM = 'FEB' then
      Result := '2'
    else if wM = 'MAR' then
      Result := '3'
    else if wM = 'APR' then
      Result := '4'
    else if wM = 'MAY' then
      Result := '5'
    else if wM = 'JUN' then
      Result := '6'
    else if wM = 'JUL' then
      Result := '7'
    else if wM = 'AUG' then
      Result := '8'
    else if wM = 'SEP' then
      Result := '9'
    else if wM = 'OCT' then
      Result := '10'
    else if wM = 'NOV' then
      Result := '11'
    else if wM = 'DEC' then
      Result := '12';
  end;
 
  procedure Delay(msecs: Integer);
  var
    FirstTickCount: longint;
  begin
    FirstTickCount := GetTickCount;
    repeat
      Application.ProcessMessages;
    until ((GetTickCount - FirstTickCount) >= longint(msecs));
  end;
 
var
  strFile: TextFile;
  strLine: String;
  wPos: Integer;
  wDiretorio_Padrao: string;
  wComando: string;
  cExe, cArq1, cArq2: string;
begin
  Result := '';
 
  try
    // diretorio padrao
    wDiretorio_Padrao := ExtractFilePath(Application.ExeName);
    cExe := '"' + wDiretorio_Padrao + 'openssl.exe"';
 
    // cópia arquivo PFX
    CopyFile(PChar(wCertificado),
      PChar(wDiretorio_Padrao + 'certificado.pfx'), true);
 
    cArq1 := '"' + wDiretorio_Padrao + 'certificado.pfx "';
    cArq2 := '"' + wDiretorio_Padrao + 'certificado.pem "';
 
    wComando := ' pkcs12 -in ' + cArq1 + ' -out ' + cArq2 +
      ' -nokeys -passin pass:' + wSenha;
    ShellExecute(Application.Handle, NIL, PChar(cExe), PChar(wComando), nil, 0);
 
    // para dar tempo do arquivo ficar disponivel para uso
    Delay(150);
 
    cArq1 := '"' + wDiretorio_Padrao + 'certificado.pem "';
    cArq2 := '"' + wDiretorio_Padrao + 'validade.txt "';
 
    wComando := ' x509 -enddate -in ' + cArq1 + ' -text -out ' + cArq2;
    ShellExecute(Application.Handle, NIL, PChar(cExe), PChar(wComando), nil, 0);
 
    // para dar tempo do arquivo ficar disponivel para uso
    Delay(150);
 
    // Lê arquivo
    if FileExists(wDiretorio_Padrao + 'validade.txt') then
    begin
      AssignFile(strFile, wDiretorio_Padrao + 'validade.txt');
      Reset(strFile);
      while not EOF(strFile) do
      begin
        Readln(strFile, strLine);
        wPos := Pos('NOT AFTER :', UpperCase(strLine));
        if (wPos <> 0) then
        begin
          Result := trim(copy(strLine, wPos + 11, 25));
          Break;
        end;
      end;
 
      CloseFile(strFile);
 
      // identica data corretamente dd/mm/aaaa
      Result := DateToStr(StrToDate(Copy(Result, 5, 2) + '/' +
        Months(Copy(Result, 1, 3)) + '/' + Copy(Result, 17, 4)));
    end
  except
  end;
 
  // apaga arquivos criados
  if FileExists(wDiretorio_Padrao + 'validade.txt') then
    DeleteFile(wDiretorio_Padrao + 'validade.txt');
  if FileExists(wDiretorio_Padrao + 'certificado.pem') then
    DeleteFile(wDiretorio_Padrao + 'certificado.pem');
  if FileExists(wDiretorio_Padrao + 'certificado.pfx') then
    DeleteFile(wDiretorio_Padrao + 'certificado.pfx');
end;

Para utilizar a função, basta chamar ela passando o caminho
do certificado digital e a senha do mesmo.
Exemplo de uso:

1
2
3
4
5
6
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(
  ValidadeCertificado('D:\certificados\meu_certificado.pfx',
  'senha certificado'));
end;
Facebook Comments Box
  • InfusTec
  • 7.579 views
  • 0 comentários
  • 30 de março de 2015

Está gostando do conteúdo? Considere pagar um cafezinho para nossa equipe!

Deixe um comentário

Ir ao topo

© 2024 Infus Soluções em Tecnologia - Todos os Direitos Reservados