Wie kann ich zwischen den beiden Stilen des öffentlichen Schlüsselformats transformieren? Ein Format ist:
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
Das andere Format ist:
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----
Zum Beispiel habe ich das Paar id_rsa / id_rsa.pub mit dem Befehl ssh-keygen generiert. Ich habe den öffentlichen Schlüssel aus id_rsa berechnet mit:
openssl rsa -in id_rsa -pubout -out pub2
dann habe ich wieder den öffentlichen Schlüssel aus id_rsa.pub berechnet mit:
ssh-keygen -f id_rsa.pub -e -m pem > pub1
Der Inhalt ist pub1 ist:
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
-----END RSA PUBLIC KEY-----
und der Inhalt von pub2 ist:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS
+rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS
EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n
oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v
Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu
lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26
ZQIDAQAB
-----END PUBLIC KEY-----
Nach meinem Verständnis enthalten pub1 und pub2 die gleichen Informationen zu öffentlichen Schlüsseln, aber sie haben ein unterschiedliches Format. Ich frage mich, wie ich zwischen den beiden Formaten wechseln kann. Kann mir jemand eine kurze Einführung in die Schleppformate zeigen?
Antworten:
Mit phpseclib eine reine PHP-RSA-Implementierung ...
Das base64-codierte Material scheint übereinzustimmen, obwohl in der Kopfzeile BEGIN PUBLIC KEY und nicht BEGIN RSA PUBLIC KEY steht. Verwenden Sie also einfach str_replace, um das zu beheben, und Sie sollten bereit sein!
quelle
Ich wollte erklären, was hier los ist.
Ein RSA "Public Key" besteht aus zwei Zahlen:
Am Beispiel Ihres öffentlichen RSA-Schlüssels lauten die beiden Zahlen:
Die Frage wird dann, wie wir diese Nummern in einem Computer speichern wollen. Zuerst konvertieren wir beide in hexadezimal:
RSA hat das erste Format erfunden
RSA hat zuerst ein Format erfunden:
Sie entschieden sich für die DER-Variante des ASN.1-Binärcodierungsstandards, um die beiden Zahlen darzustellen [1] :
Die endgültige binäre Codierung in ASN.1 lautet:
Wenn Sie dann alle diese Bytes zusammen ausführen und Base64 codieren, erhalten Sie:
RSA Labs sagte dann, fügen Sie einen Header und einen Trailer hinzu:
Fünf Bindestriche und die Wörter
BEGIN RSA PUBLIC KEY
. Dies ist Ihr öffentlicher PEM DER ASN.1 PKCS # 1 RSA-SchlüsselNicht nur RSA
Danach kamen andere Formen der Kryptographie mit öffentlichen Schlüsseln hinzu:
Als es an der Zeit war, einen Standard für die Darstellung der Parameter dieser Verschlüsselungsalgorithmen zu erstellen , haben die Leute viele der gleichen Ideen übernommen, die RSA ursprünglich definiert hatte:
BEGIN PUBLIC KEY
Aber anstatt zu verwenden:
-----BEGIN RSA PUBLIC KEY-----
-----BEGIN DH PUBLIC KEY-----
-----BEGIN EC PUBLIC KEY-----
Sie beschlossen stattdessen, die Objektkennung (Object Identifier, OID) der folgenden Elemente anzugeben. Im Fall eines öffentlichen RSA-Schlüssels bedeutet dies:
1.2.840.113549.1.1.1
Für den öffentlichen RSA-Schlüssel war es also im Wesentlichen:
Jetzt haben sie SubjectPublicKeyInfo erstellt, was im Grunde genommen Folgendes ist:
In der tatsächlichen DER ASN.1-Definition lautet:
Das gibt Ihnen eine ASN.1 von:
Die endgültige binäre Codierung in ASN.1 lautet:
Und wie zuvor nehmen Sie alle diese Bytes, Base64 codiert sie und Sie erhalten Ihr zweites Beispiel:
Fügen Sie den etwas anderen Header und Trailer hinzu und Sie erhalten:
Und dies ist Ihr öffentlicher X.509 SubjectPublicKeyInfo / OpenSSL PEM-Schlüssel [2] .
Mach es richtig oder hacke es
Jetzt, da Sie wissen, dass die Codierung keine Zauberei ist, können Sie alle Teile schreiben, die zum Parsen des RSA-Moduls und des Exponenten erforderlich sind. Oder Sie können erkennen, dass die ersten 24 Bytes nur über den ursprünglichen PKCS # 1-Standard hinzugefügt werden
Diese ersten 24 Bytes sind "neue" Dinge, die hinzugefügt wurden:
Und aufgrund eines außergewöhnlichen Zufalls von Glück und Glück:
Denn in Base64: 3-Bytes werden vier Zeichen:
Das heißt, wenn Sie Ihren zweiten öffentlichen X.509-Schlüssel verwenden, entsprechen die ersten 32 Zeichen nur neu hinzugefügten Elementen:
Wenn Sie die ersten 32 Zeichen entfernen und in BEGIN RSA PUBLIC KEY ändern :
Sie haben genau das, was Sie wollten - das ältere
RSA PUBLIC KEY
Format.quelle
Ich fand diese Website eine gute technische Erklärung für die verschiedenen Formate: https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem
"BEGIN RSA PUBLIC KEY" ist PKCS # 1, das nur RSA-Schlüssel enthalten kann.
"BEGIN PUBLIC KEY" ist PKCS # 8, das eine Vielzahl von Formaten enthalten kann.
Wenn Sie sie nur über die Befehlszeile konvertieren möchten, ist "openssl rsa" dafür gut geeignet.
So konvertieren Sie von PKCS # 8 zu PKCS # 1:
So konvertieren Sie von PKCS # 1 zu PKCS # 8:
quelle
unknown option -RSAPublicKey_in
Obwohl die obigen Kommentare zu 32-Byte-Headern, OID-Formaten und dergleichen interessant sind, sehe ich persönlich nicht das gleiche Verhalten, vorausgesetzt, ich verstehe den Punkt. Ich dachte, es könnte hilfreich sein, dies weiter zu untersuchen, was die meisten für übermäßig detailliert halten. Nichts geht über das Übermaß hinaus.
Zu Beginn habe ich einen privaten RSA-Schlüssel erstellt und überprüft:
(Oh, Horror! Ich habe einen privaten Schlüssel freigelegt. Meh ...)
Ich extrahiere und zeige seinen öffentlichen Schlüssel an:
Es kommt also vor, dass es einen anderen Ausgabeparameter für öffentliche Schlüssel gibt (wie in einem früheren Kommentar erwähnt). Ich extrahiere und zeige den öffentlichen Schlüssel stattdessen mit diesem Schlüsselwort an:
Gut gut. Diese beiden Werte für öffentliche Schlüssel sind nicht identisch, obwohl sie von demselben privaten Schlüssel abgeleitet sind. Oder sind sie gleich? Ich schneide die beiden öffentlichen Schlüsselzeichenfolgen aus und füge sie in ihre eigenen Dateien ein. Anschließend überprüfe ich jeweils die Module:
Die ‚Pubin‘ sagt rsa , dass dies wirklich ist , sollte einen öffentlichen Schlüssel sein, und sich nicht beschweren , dass es nicht ein privater Schlüssel.
Jetzt nehmen wir den öffentlichen RSA-Schlüssel, zeigen den Modul an und wandeln ihn in einen einfachen alten 'öffentlichen Schlüssel' um (wieder müssen wir ihm sagen, dass die Eingabe ein öffentlicher Schlüssel ist):
Gleicher Modul und gleicher Wert für 'öffentlicher Schlüssel' werden angezeigt. Um die Dinge interessanter zu machen (für mich jedenfalls), erhalten wir, wenn wir das Schlüsselwort RSAPublicKey_out verwenden, Folgendes :
... und wenn wir den einfachen alten "öffentlichen Schlüssel" in einen öffentlichen RSA-Schlüssel umwandeln:
... unerbittlich weiter marschieren, und obwohl wir dies erst vor ein paar Befehlen getan haben, um den Punkt zu verdeutlichen, drehen wir die Dinge um, damit die Transmogrifikation von RSA zu einem einfachen alten "öffentlichen Schlüssel" erfolgt:
... was uns dorthin zurückbringt, wo wir angefangen haben. Was haben wir gelernt?
Zusammenfassung: Die Schlüssel sind intern gleich, sie sehen nur anders aus. In einem früheren Kommentar wurde darauf hingewiesen, dass das RSA-Schlüsselformat in PKCS # 1 definiert wurde und das einfache alte 'öffentliche Schlüssel'-Format in PKCS # 8 definiert wurde. Wenn Sie jedoch ein Formular bearbeiten, wird es nicht in das andere umgewandelt. Hoffentlich habe ich diese Unterscheidung jetzt zu Tode geschlagen.
Für den Fall, dass noch ein Funke Leben übrig ist, lassen Sie uns dies ein bisschen mehr auspeitschen und auf das Zertifikat verweisen, das ursprünglich vor so langer Zeit mit dem privaten RSA-Schlüssel generiert wurde, und dessen öffentlichen Schlüssel und Modul untersuchen:
... und sie alle lebten glücklich bis ans Ende ihrer Tage: Das Zertifikat hat den gleichen Modulwert wie der öffentliche RSA-Schlüssel, der private RSA-Schlüssel und der einfache alte 'öffentliche Schlüssel'. Das Zertifikat enthält denselben einfachen alten Wert für den öffentlichen Schlüssel, den wir zuvor gesehen haben, obwohl es mit einer Datei signiert wurde, die als privater RSA-Schlüssel markiert ist. Man kann mit Sicherheit sagen, dass es einen Konsens gibt.
Es gibt kein 'RSAPublicKey_out'-äquivalentes Schlüsselwort im X509-Quadranten der OpenSSL-Galaxie, daher können wir das nicht versuchen, obwohl der Modulwert als "RSA-Schlüsselmodul" beschrieben wird, von dem ich annehme, dass er so nah wie möglich ist.
Wie das alles mit einem von der DSA signierten Zertifikat aussehen würde, weiß ich nicht.
Mir ist klar, dass dies die ursprüngliche Frage nicht beantwortet, aber vielleicht einen nützlichen Hintergrund bietet. Wenn nicht, entschuldige ich mich. Zumindest Dinge, die nicht zu tun sind und Annahmen, die nicht zu treffen sind.
Zweifellos hat man die leicht irritierende Wiederholung des "Schreibens des RSA-Schlüssels" bemerkt, wenn es so etwas nicht tut. Ich gehe davon aus, dass gemeint ist, dass das rsa-Modul den einfachen alten öffentlichen Schlüssel als echten RSA-Schlüssel erkennt und deshalb immer wieder auf "RSA-Schlüssel" spielt (und es ist schließlich das rsa-Modul). Wenn ich mich richtig erinnere, hat die generische EVP_PKEY-Struktur eine Vereinigung für alle Schlüsseltypen, wobei jeder Schlüsseltyp seinen eigenen speziellen Wertesatz hat (die hilfreich benannten g, w, q und andere Konsonanten).
Abschließend stelle ich fest, dass es eine Beschwerde bezüglich Programmierung und Entwicklung gab; Jetzt hat jeder OpenSSL-Befehl offensichtlich den entsprechenden Code, und wenn man alle Wunder erforschen möchte, die OpenSSL heute programmiert, scheint die Befehlszeile ein vernünftiger Ausgangspunkt zu sein. In diesem speziellen Fall (da ich momentan ein aktuelles Cygwin verwende) könnte man zunächst \ openssl-1.0.2f \ apps \ rsa.c und (vorausgesetzt, man hat eine hohe Toleranz für Makros) \ openssl-1.0 überprüfen. 2f \ crypto \ pem \ pem_all.c
quelle
Der einzige Unterschied zwischen pub1 und pub2 neben der Kopf- / Fußzeile besteht in dieser zusätzlichen Zeichenfolge in pub2 :
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
. Wenn Sie das entfernen, ist die Base 64 mit der in pub1 identisch.Die zusätzliche Zeichenfolge entspricht der Algorithmus-ID gemäß dieser Antwort .
quelle