Ich bin über ein ähnliches Problem gestolpert, als ich neulich "JSON Web Keys" auswerten wollte, um mit diesen Zertifikaten dann wiederum ein Token zu verifizieren. Da kam auch etwas in diesem DER-Format vor. Mein Code hier wandelt dieses X509/DER-kodierte Gedöns in einen ganz "normalen" String im PEM-Format um. Dabei helfen die Indys insofern, weil sie halt die ganzen Befehle der OpenSSL-Bibliothek bereitstellen, d.h., die eigentliche Arbeit macht OpenSSL und dort findet man auch die Doku zu den ganzen nötigen Kommandos.
Hier also mein Code - ob er
genau zu deinem Problem passt, kann ich nicht sagen, aber ich vermute, es wird zumindest einiges dabei sein, was in eine passende Richtung geht:
Delphi-Quellcode:
function TwebConfig.ConvertBaseX509ToPEM(aWebKey:
string):
string;
(* Wenn wir ein Zertifikat vom OAuth-Server als JSON Web Key abfragen, so ist das dort in einem etwas anstrengenden
Format angegeben, dass wir nicht direkt verwenden können. Was wir wollen: ein ganz normales Zertifikat im gängingen
PEM-Format. Was wir haben: Einen Base64-String, welcher das Zertifikat im Format X509 enthält und das wiederum
im Format "DER" (irgendwas aus den Achtzigern...) kodiert. Wenn man ein paarmal den Kopf gegen die Wand gehauen
hat, versteht man irgendwann, wie man die OpenSSL-Bibliothek nutzen kann, um zum gewünschten PEM-Format zu kommen.
*)
var
byteArray: TBytes;
bytePubKey: TBytes;
certX509: PX509;
bio: PBIO;
PArray: Pointer;
begin
if IdSSLOpenSSLHeaders.Load
then begin
try
byteArray:=TNetEncoding.Base64.DecodeStringToBytes(aWebKey);
// das Array und auch einen Pointer auf das Array dürfen wir an d2i_x509 nicht direkt übergeben, sondern müssen
// ihn in eine andere Pointer-Variable kopieren, da d2i diesen Pointer nachher hinter das übergebene Byte-Array
// zeigen lässt. Wir würden den Speichermanager zerschießen, wenn wir direkt das Array bzw. einen Pointer darauf übergeben.
// Und ja: wir übergeben tatsächlich einen Pointer auf den Pointer - somit kann eben der eigentliche Pointer
// geändert werden (letztlich wird so also ein "var-Parameter" realisiert.
PArray:=@byteArray[0];
certX509:=d2i_X509(
nil,@PArray,length(byteArray));
if certX509<>
nil then begin
bio:=BIO_new(BIO_s_mem);
PEM_write_bio_X509(bio,certX509);
SetLength(bytePubKey,bio.num_write);
BIO_read(bio,bytePubKey,BIo.num_write);
Result:=string(PAnsiChar(@bytePubKey[0]));
BIO_free(bio);
X509_free(certX509);
SetLength(bytePubKey,0);
end else
Result:='
';
except
on e:
exception do begin
Result:='
';
fLastError:=_('
Fehler bei der Verarbeitung des Öffentlichen Schlüssels aus dem JSON Web Key.')+'
'+_('
Fehlermeldung:')+'
'+e.
Message;
end;
end;
SetLength(byteArray,0);
end;
end;