如果我想检查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
的指针,这样我就迷失在那里
答案 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标准,可以是YYYYMMDDHHNNSS
或YYYYMMDDHHNNSS
,因此我只是规定返回的值始终为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}}