Hallo zusammen,
ich bin ja dabei ein wenig an der Lackierung des Klarlacks der Schutzhülle der Oberfläche der Kryptologie zu kratzen... oder so ähnlich. Ich bin dafür auf die
Windows Crypt API umgestiegen, da die mich relativ schnell und mit zahlreichen guten Beispielen zu einem Teilziel (Verschlüsselung mit AES-128) geführt hatte. Jetzt scheitere ich jedoch kläglich an der RSA Verschlüsselung, also nicht der Verschlüsselung an sich, sondern daran den Public Key aus gleich zwei verschiedenen Keyfiles (eine .der und eine .cer mit dem gleichen Key zum Inhalt) auszulesen. Ich habe also mehrere Möglichkeiten zum Auslesen, und nicht eine klappt. Ich bekomme immer "ASN1 Ungültiger Kennzeichenwert". Wenn ich das gleiche Zertifikat in Windows öffne, kann ich den Public Key direkt auslesen... Es ist also nicht kaputt. Hier mal der Code wie ich versuche das Zertifikat zu lesen:
Delphi-Quellcode:
try
CertPath := 'c:\sinnloserPfad\data';
// Beide Formate liegen vor, egal welche Datei ich einlese...immer das gleiche Ergebnis
pubCert := TFileStream.Create(CertPath + '\zpr_prod_public_cert.cer', fmOpenRead or fmShareDenyNone);
// pubCert := TFileStream.Create(CertPath + '\zpr_prod_public_key.der', fmOpenRead or fmShareDenyNone);
try
SetLength(Buffer, pubCert.Size);
BufLen := pubCert.read(Pointer(Buffer)^, pubCert.Size); // sollte ich eventuell an dieser Stelle noch irgendwas kodieren/dekodieren Base64 oder so?
finally
pubCert.Free;
end;
except
RaiseLastOSError;
Exit;
end;
if Length(Buffer) > 1 then
begin
try
DataLen := 0;
// die folgende Zeile müsste es eigentlich schon tun... Das Ergebnis-Objekt ist aber leer, und der Fehler ist eingangs genannter "ASN1 Ungültig...."
CertContext := CertCreateCertificateContext(X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, @Buffer[0], BufLen);
if CertContext = nil then // Dann eben die andere Variante, die aber zu exakt dem gleichen Fehler führt :(
Win32Check(CryptDecodeObjectEx(X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, @Buffer[0], BufLen, CRYPT_ENCODE_ALLOC_FLAG, nil, @PublicKeyInfo, DataLen))
else
begin // hier kommen wir gar nicht mehr hin...
hCProv := __CryptAcquireContext(PROV_RSA_FULL);
if Win32Check(CryptImportPublicKeyInfo(hCProv, X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, @certcontext.pCertInfo.SubjectPublicKeyInfo, hKey)) then
begin
DataLen := Length(einKey);
BufLen := DataLen;
Win32Check(CryptEncrypt(hkey, 0, True, 0, @EinKey[0], DataLen, BufLen));
SetLength(einKey, DataLen);
end;
end;
finally
Win32Check(CryptReleaseContext(hCProv, 0));
end;
end;
Hat jemand eine Idee? Wo mache ich den Fehler?
Sherlock