从本地存储在Android中的client-cert.pem文件中获取SSL证书过期日期

时间:2016-03-11 15:41:15

标签: android delphi ssl-certificate firemonkey indy

如果我想检查SSL证书的到期日期,我可以使用与IdHTTP

相关联的IdSSLIOHandlerSocketOpenSSL
IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL1;

然后点按OnVerifyPeer

function TForm1.IdSSLIOHandlerSocketOpenSSL1VerifyPeer(Certificate: TIdX509;
  AOk: Boolean; ADepth, AError: Integer): Boolean;
begin
    Showmessage(Certificate.notAfter));
end;

最后对我要检索服务器证书的服务器执行IdHTTP.Get,这样可行。

BUT

我的Android设备上本地存储了一个客户端证书,该证书随App一起部署,我将如何访问证书?

意味着如何将证书加载到TidX509对象中? TidX509的构造函数需要PX509,然后将其分配给记录X509的指针,这样我就迷失在那里

1 个答案:

答案 0 :(得分:1)

正如Remy指出的那样,我只需看看OpenSSL如何从内存中加载证书以获取证书

但首先,您从读取证书function StringUTCtoDATETIME(UTCString : String) : TDateTime; begin if UTCString.Length = 13 then begin Delete(UTCString,UTCString.Length,1); Delete(UTCString,0,2); Insert(Copy(FormatDateTime('yyyy',Now),0,2),UTCString,0); end else begin Delete(UTCString,UTCString.Length,1); end; Result := EncodeDateTime(StrToInt(Copy(UTCString,1,4)),StrToInt(Copy(UTCString,5,2)),StrToInt(Copy(UTCString,7,2)), StrToInt(Copy(UTCString,9,2)),StrToInt(Copy(UTCString,11,2)),StrToInt(Copy(UTCString,13,2)),000); end; 获得的值是字符串中的UTC时间值,因此您需要这样的内容

YYMMDDHHNNSS

该值符合ISO8601标准,可以是YYYYMMDDHHNNSSYYYYMMDDHHNNSS,因此我只是规定返回的值始终为function ReturnCertificateExpiryDate(const AFileName: String): TDateTime; var LM : TMemoryStream; LX: PX509; LB: PBIO; begin LM := nil; try LM := TMemoryStream.Create; LM.LoadFromFile(AFileName); except SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_SYS_LIB); LM.Free; Exit; end; if LM = nil then begin Exit; end; try LB := BIO_new_mem_buf(LM.Memory, LM.Size); if Assigned(LB) then begin LX := PEM_read_bio_X509(LB, nil, nil, nil); if LX<> nil then begin RESULT := StringUTCtoDATETIME(String(LX.cert_info.validity.notAfter.data)); end; end; finally FreeAndNil(LM); end; end;

为了得到这个值,我们将它加载到内存中并像Indy一样使用它。

var
    Context : TIdSSLContext;
begin
  Context := TIdSSLContext.Create;
  ShowMessage(FormatDateTime('yyyy-mm-dd hh:nn:ss',(ReturnCertificateExpiryDate(TPath.Combine(TPath.GetDocumentsPath, 'client-cert.pem')))));
end;

您还需要创建一个Context变量

{{1}}