it-swarm.com.de

Wie kann ich zwischen den beiden Formaten für öffentliche Schlüssel wechseln, nämlich "BEGIN RSA PUBLIC KEY" und "BEGIN PUBLIC KEY"?

Wie kann ich zwischen den beiden Formaten für öffentliche Schlüssel wechseln? Ein Format ist:

-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

das andere Format ist:

-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

ich habe zum Beispiel das Paar id_rsa/id_rsa.pub mit dem Befehl ssh-keygen generiert und den öffentlichen Schlüssel aus id_rsa berechnet mit:

openssl rsa -in id_rsa -pubout -out pub2 

dann berechnete ich den öffentlichen Schlüssel aus id_rsa.pub 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 dieselben öffentlichen Schlüsselinformationen, 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 geben?

80
welkinwalker

Mit phpseclib, eine reine PHP RSA-Implementierung ...

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$rsa->loadKey('-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS
+rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS
EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n
oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v
Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu
lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26
ZQIDAQAB
-----END PUBLIC KEY-----');
$rsa->setPublicKey();

echo $rsa->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW);

Das base64-codierte Zeug scheint zu passen, obwohl der Header BEGIN PUBLIC KEY und nicht BEGIN RSA PUBLIC KEY lautet. Verwenden Sie einfach str_replace, um das zu beheben, und schon kann es losgehen!

10
user216741

Ich wollte erklären, was hier vor sich geht.

Ein RSA "Public Key" besteht aus zwei Zahlen:

  • der Modul (z. B. eine 2.048-Bit-Zahl)
  • der Exponent (normalerweise 65.537)

Am Beispiel Ihres öffentlichen RSA-Schlüssels lauten die beiden Zahlen:

  • Modul : 297,056,429,939,040,947,991,047,334,197,581,225,628,107,021,573,849,359, 042,679,698,093,131,908,015,712,695,688,944,173,317,630,555,849,768,647,118,986,535,684,992,447,654, 339,728,777,985,990,170,679,511,111,819,558,063,246,667,855,023,730,127,805,401,069,042,322,764,200, 545.883.378.826.983.730.553.730.138.478.384.327.116.513.143.842.816.383.440.639.376.515.039.682.874.046.227.217.032.079.079.790.098.143.158.087.443.017.552.531.393.264.852.461.292.775.129.262.080.851.633.535.934.010.704.122.673.027.067.442.627.059.982.393.297.716.922.243.940.155.855.127.430.302.323.883.824.137.412.883.916.794.359.982.603.439.112.095.116.831.297.809.626.059.569.444.750.808.699.678.211.904.501.083.183.234.323.797.142.810.155.862.553.705.570.600.021.649.944.369.726.123.996.534.870.137.000.784.980.673.984.909.570.977.377.882.585.701
  • Exponent : 65.537

Die Frage wird dann, wie wir diese Zahlen in einem Computer speichern wollen. Zuerst konvertieren wir beide in hexadezimal:

  • Modulus : EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65
  • Exponent : 010001

RSA hat das erste Format erfunden

RSA hat zuerst ein Format erfunden:

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

Sie entschieden sich für die DER-Variante des binären Codierungsstandards ASN.1, um die beiden Zahlen darzustellen [1] :

SEQUENCE (2 elements)
   INTEGER (2048 bit): 0282010100EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65
   INTEGER (24 bit): 010001

Die endgültige Binärkodierung in ASN.1 lautet:

30 82 01 0A      ;sequence (0x10A bytes long)
   02 82 01 01   ;integer (0x101 bytes long)
      00 EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65
   02 03         ;integer (3 bytes long)
      010001

Wenn Sie dann alle diese Bytes zusammen ausführen und Base64 codiert, erhalten Sie:

MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB

RSA Labs fügte dann einen Header und einen Trailer hinzu:

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
-----END RSA PUBLIC KEY-----

Fünf Bindestriche und die Worte BEGIN RSA PUBLIC KEY. Das ist Ihr PEM DER ASN.1 PKCS # 1 RSA Public Key

  • PEM: Synonym für base64
  • DER: eine Variante der ASN.1-Codierung
  • ASN.1: das verwendete binäre Codierungsschema
  • PKCS # 1: Die formale Spezifikation, die die Darstellung eines öffentlichen Schlüssels als Struktur vorschreibt, die aus einem Modul gefolgt von einem Exponenten besteht
  • Öffentlicher RSA-Schlüssel: Der verwendete Algorithmus für den öffentlichen Schlüssel

Nicht nur RSA

Danach kamen andere Formen der Kryptographie mit öffentlichen Schlüsseln hinzu:

  • Diffie-Hellman
  • Ellicptic Curve

Als es an der Zeit war, einen Standard für die Darstellung der Parameter dieser Verschlüsselungsalgorithmen zu erstellen, übernahmen die Leute viele der Ideen, die RSA ursprünglich definiert hatte:

  • verwenden Sie die binäre Kodierung ASN.1
  • base64 es
  • wickeln Sie es mit fünf Bindestrichen
  • und die Worte 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) für das, was folgen soll, anzugeben. Im Fall eines öffentlichen RSA-Schlüssels bedeutet dies:

  • RSA PKCS # 1 : 1.2.840.113549.1.1.1

Für den öffentlichen RSA-Schlüssel war es also im Wesentlichen:

public struct RSAPublicKey {
   INTEGER modulus,
   INTEGER publicExponent 
}

Jetzt haben sie SubjectPublicKeyInfo erstellt.

public struct SubjectPublicKeyInfo {
   AlgorithmIdentifier algorithm,
   RSAPublicKey subjectPublicKey
}

In der tatsächlichen DER ASN.1-Definition ist:

SubjectPublicKeyInfo  ::=  SEQUENCE  {
    algorithm  ::=  SEQUENCE  {
        algorithm               OBJECT IDENTIFIER, -- 1.2.840.113549.1.1.1 rsaEncryption (PKCS#1 1)
        parameters              ANY DEFINED BY algorithm OPTIONAL  },
    subjectPublicKey     BIT STRING {
        RSAPublicKey ::= SEQUENCE {
            modulus            INTEGER,    -- n
            publicExponent     INTEGER     -- e
        }
}

Das gibt Ihnen einen ASN.1 von:

SEQUENCE (2 elements)
   SEQUENCE (2 elements)
      OBJECT IDENTIFIER 1.2.840.113549.1.1.1
      NULL
   BIT STRING (1 element)
      SEQUENCE (2 elements)
         INTEGER (2048 bit): 0282010100EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65
         INTEGER (24 bit): 010001

Die endgültige Binärkodierung in ASN.1 lautet:

30 82 01 22          ;SEQUENCE (0x122 bytes = 290 bytes)
|  30 0D             ;SEQUENCE (0x0d bytes = 13 bytes) 
|  |  06 09          ;OBJECT IDENTIFIER (0x09 = 9 bytes)
|  |  2A 86 48 86   
|  |  F7 0D 01 01 01 ;hex encoding of 1.2.840.113549.1.1
|  |  05 00          ;NULL (0 bytes)
|  03 82 01 0F 00    ;BIT STRING  (0x10f = 271 bytes)
|  |  30 82 01 0A       ;SEQUENCE (0x10a = 266 bytes)
|  |  |  02 82 01 01    ;INTEGER  (0x101 = 257 bytes)
|  |  |  |  00             ;leading zero of INTEGER
|  |  |  |  EB 50 63 99 F5 C6 12 F5  A6 7A 09 C1 19 2B 92 FA 
|  |  |  |  B5 3D B2 85 20 D8 59 CE  0E F6 B7 D8 3D 40 AA 1C 
|  |  |  |  1D CE 2C 07 20 D1 5A 0F  53 15 95 CA D8 1B A5 D1 
|  |  |  |  29 F9 1C C6 76 97 19 F1  43 58 72 C4 BC D0 52 11 
|  |  |  |  50 A0 26 3B 47 00 66 48  9B 91 8B FC A0 3C E8 A0
|  |  |  |  E9 FC 2C 03 14 C4 B0 96  EA 30 71 7C 03 C2 8C A2  
|  |  |  |  9E 67 8E 63 D7 8A CA 1E  9A 63 BD B1 26 1E E7 A0  
|  |  |  |  B0 41 AB 53 74 6D 68 B5  7B 68 BE F3 7B 71 38 28
|  |  |  |  38 C9 5D A8 55 78 41 A3  CA 58 10 9F 0B 4F 77 A5
|  |  |  |  E9 29 B1 A2 5D C2 D6 81  4C 55 DC 0F 81 CD 2F 4E 
|  |  |  |  5D B9 5E E7 0C 70 6F C0  2C 4F CA 35 8E A9 A8 2D 
|  |  |  |  80 43 A4 76 11 19 55 80  F8 94 58 E3 DA B5 59 2D
|  |  |  |  EF E0 6C DE 1E 51 6A 6C  61 ED 78 C1 39 77 AE 96 
|  |  |  |  60 A9 19 2C A7 5C D7 29  67 FD 3A FA FA 1F 1A 2F 
|  |  |  |  F6 32 5A 50 64 D8 47 02  8F 1E 6B 23 29 E8 57 2F 
|  |  |  |  36 E7 08 A5 49 DD A3 55  FC 74 A3 2F DD 8D BA 65
|  |  |  02 03          ;INTEGER (03 = 3 bytes)
|  |  |  |  010001

Und wie zuvor nehmen Sie all diese Bytes, codieren sie mit Base64, und Sie erhalten Ihr zweites Beispiel:

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS
+rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS
EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n
oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v
Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu
lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26
ZQIDAQAB   

Fügen Sie den etwas anderen Header und Trailer hinzu, und Sie erhalten:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS
+rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS
EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n
oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v
Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu
lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26
ZQIDAQAB   
-----END PUBLIC KEY-----

Und dies ist Ihr öffentlicher X.509-Schlüssel SubjectPublicKeyInfo/OpenSSL PEM [2] .

Mach es richtig oder hack es

Jetzt, da Sie wissen, dass die Codierung nicht magisch 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 neues Material über den ursprünglichen PKCS # 1-Standard hinzugefügt werden

30 82 01 22          ;SEQUENCE (0x122 bytes = 290 bytes)
|  30 0D             ;SEQUENCE (0x0d bytes = 13 bytes) 
|  |  06 09          ;OBJECT IDENTIFIER (0x09 = 9 bytes)
|  |  2A 86 48 86   
|  |  F7 0D 01 01 01 ;hex encoding of 1.2.840.113549.1.1
|  |  05 00          ;NULL (0 bytes)
|  03 82 01 0F 00    ;BIT STRING  (0x10f = 271 bytes)
|  |  ...

Und aufgrund eines außergewöhnlichen Zufalls von Glück und Erfolg:

24 Bytes entsprechen genau 32 Base64-codierten Zeichen

Das heißt, wenn Sie Ihren zweiten öffentlichen X.509-Schlüssel nehmen und die ersten 32 Zeichen trennen:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
-----END PUBLIC KEY-----

entfernen Sie die ersten 32 Zeichen und ändern Sie sie in BEGIN RSA PUBLIC KEY :

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
-----END RSA PUBLIC KEY-----

Sie haben genau das, was Sie wollten.

242
Ian Boyd

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 mit der Kommandozeile konvertieren wollen, ist "openssl rsa" dafür gut.

So konvertieren Sie von PKCS # 8 nach PKCS # 1:

openssl rsa -pubin -in <filename> -RSAPublicKey_out

So konvertieren Sie von PKCS # 1 nach PKCS # 8:

openssl rsa -RSAPublicKey_in -in <filename> -pubout
42
Vincent Povirk

Obwohl die obigen Kommentare zu 32-Byte-Headern, OID Formaten und dergleichen interessant sind, sehe ich persönlich nicht dasselbe Verhalten, vorausgesetzt, ich verstehe den Punkt. Ich dachte, es könnte hilfreich sein Erforschen Sie dies weiter in den Details, von denen die meisten denken, dass sie übermäßig sind.

Zunächst habe ich einen privaten RSA-Schlüssel erstellt und überprüft:

>openssl rsa -in newclient_privatekey.pem  -check
RSA key ok
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCn/OlFk7vLRQ6dBiNQkvjnhm4pOYWo+GeAEmU4N1HPZj1dxv70
4hm80eYc7h12xc7oVcDLBdHByGAGBpQfpjgdPyozC/zSqcuU6iBrvzDTpyG1zhIG
76KrcjdbX6PlKAPO9r/dCRmUijFhVoUlY6ywGknmLBrtZkLkBhchgYnMswIDAQAB
AoGAQaJ5aivspeEXcpahWavzAFLv27+Tz48usUV+stY6arRhqbBEkV19/N5t8EPA
01U6IGDQ8QIXEIW/rtsHKM6DAZhAbakPDJhJRatcMzJ08ryIkP/c3+onkTquiveG
brw7xzn6Xa8ls04aQ6VQR4jxXUjV5bB72pFZnGRoAmS2NiECQQDUoISbmTGjnHM+
kEfunNTXbNmKklwTYhyZaSVsSptnD7CvLWB4qB/g4h2/HjsELag6Z7SlWuYr7tba
H3nBYn35AkEAykFRudMqlBy3XmcGIpjxOD+7huyViPoUpy3ui/Bj3GbqsbEAt9cR
PyOJa1VFa2JqShta1Tdep8LJv1QvgvY7CwJBAML+al5gAXvwEGhB3RXg0fi2JFLG
opZMFbpDCUTkrtu3MeuVC7HbTVDpTSpmSO0uCed2D97NG+USZgsnbnuBHdECQQCw
S3FWPXdetQ0srzaMz61rLzphaDULuZhpBMNqnTYeNmMaUcPjewagd3Rf52rkKFun
juKE+Yd7SXGbYWEskT5zAkAD7tbNwe5ryD2CT71jrY/5uXMR2yg/A4Ry2ocZkQUp
iGflLrHnODvHO5LYLBlSKpjanBceYHJLuMFNZruf7uBM
-----END RSA PRIVATE KEY-----

(Oh, Horror! Ich habe einen privaten Schlüssel freigelegt. Meh ...)

Ich extrahiere und zeige seinen öffentlichen Schlüssel an:

>openssl rsa -in newclient_privatekey.pem -pubout
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn/OlFk7vLRQ6dBiNQkvjnhm4p
OYWo+GeAEmU4N1HPZj1dxv704hm80eYc7h12xc7oVcDLBdHByGAGBpQfpjgdPyoz
C/zSqcuU6iBrvzDTpyG1zhIG76KrcjdbX6PlKAPO9r/dCRmUijFhVoUlY6ywGknm
LBrtZkLkBhchgYnMswIDAQAB
-----END PUBLIC KEY-----

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:

>openssl rsa -in newclient_privatekey.pem -RSAPublicKey_out
writing RSA key
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAKf86UWTu8tFDp0GI1CS+OeGbik5haj4Z4ASZTg3Uc9mPV3G/vTiGbzR
5hzuHXbFzuhVwMsF0cHIYAYGlB+mOB0/KjML/NKpy5TqIGu/MNOnIbXOEgbvoqty
N1tfo+UoA872v90JGZSKMWFWhSVjrLAaSeYsGu1mQuQGFyGBicyzAgMBAAE=
-----END RSA PUBLIC KEY-----

Gut gut. Diese beiden öffentlichen Schlüsselwerte sind nicht identisch, obwohl sie von demselben privaten Schlüssel abgeleitet sind. Oder sind sie gleich? Ich schneide die beiden Strings des öffentlichen Schlüssels aus und füge sie in ihre eigenen Dateien ein. Anschließend überprüfe ich jedes Modul:

>openssl rsa -in newclient_publickey.pem -pubin -modulus
Modulus=
A7FCE94593BBCB450E9D06235092F8E7
866E293985A8F867801265383751CF66
3D5DC6FEF4E219BCD1E61CEE1D76C5CE
E855C0CB05D1C1C8600606941FA6381D
3F2A330BFCD2A9CB94EA206BBF30D3A7
21B5CE1206EFA2AB72375B5FA3E52803
CEF6BFDD0919948A316156852563ACB0
1A49E62C1AED6642E40617218189CCB3
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn/OlFk7vLRQ6dBiNQkvjnhm4p
OYWo+GeAEmU4N1HPZj1dxv704hm80eYc7h12xc7oVcDLBdHByGAGBpQfpjgdPyoz
C/zSqcuU6iBrvzDTpyG1zhIG76KrcjdbX6PlKAPO9r/dCRmUijFhVoUlY6ywGknm
LBrtZkLkBhchgYnMswIDAQAB
-----END PUBLIC KEY-----

Das 'pubin' sagt rsa, dass dies wirklich ist ​​ein öffentlicher Schlüssel sein soll, und beklagen Sie sich nicht, dass es kein privater Schlüssel ist.

Nun 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):

>openssl rsa -in newclient_rsapublickey.pem -RSAPublicKey_in -modulus
Modulus=
A7FCE94593BBCB450E9D06235092F8E7
866E293985A8F867801265383751CF66
3D5DC6FEF4E219BCD1E61CEE1D76C5CE
E855C0CB05D1C1C8600606941FA6381D
3F2A330BFCD2A9CB94EA206BBF30D3A7
21B5CE1206EFA2AB72375B5FA3E52803
CEF6BFDD0919948A316156852563ACB0
1A49E62C1AED6642E40617218189CCB3
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn/OlFk7vLRQ6dBiNQkvjnhm4p
OYWo+GeAEmU4N1HPZj1dxv704hm80eYc7h12xc7oVcDLBdHByGAGBpQfpjgdPyoz
C/zSqcuU6iBrvzDTpyG1zhIG76KrcjdbX6PlKAPO9r/dCRmUijFhVoUlY6ywGknm
LBrtZkLkBhchgYnMswIDAQAB
-----END PUBLIC KEY-----

Das gleiche Modul und der gleiche Wert für den öffentlichen Schlüssel werden angezeigt. Um die Sache (für mich jedenfalls) interessanter zu machen, erhalten wir beim Tippen auf das Schlüsselwort RSAPublicKey_out Folgendes:

>openssl rsa -in newclient_rsapublickey.pem -RSAPublicKey_in -modulus -RSAPublicKey_out
Modulus=
A7FCE94593BBCB450E9D06235092F8E7
866E293985A8F867801265383751CF66
3D5DC6FEF4E219BCD1E61CEE1D76C5CE
E855C0CB05D1C1C8600606941FA6381D
3F2A330BFCD2A9CB94EA206BBF30D3A7
21B5CE1206EFA2AB72375B5FA3E52803
CEF6BFDD0919948A316156852563ACB0
1A49E62C1AED6642E40617218189CCB3
writing RSA key
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAKf86UWTu8tFDp0GI1CS+OeGbik5haj4Z4ASZTg3Uc9mPV3G/vTiGbzR
5hzuHXbFzuhVwMsF0cHIYAYGlB+mOB0/KjML/NKpy5TqIGu/MNOnIbXOEgbvoqty
N1tfo+UoA872v90JGZSKMWFWhSVjrLAaSeYsGu1mQuQGFyGBicyzAgMBAAE=
-----END RSA PUBLIC KEY-----

... und wenn wir den einfachen alten "öffentlichen Schlüssel" in einen öffentlichen RSA-Schlüssel umwandeln:

>openssl rsa -in newclient_publickey.pem -pubin -RSAPublicKey_out
writing RSA key
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAKf86UWTu8tFDp0GI1CS+OeGbik5haj4Z4ASZTg3Uc9mPV3G/vTiGbzR
5hzuHXbFzuhVwMsF0cHIYAYGlB+mOB0/KjML/NKpy5TqIGu/MNOnIbXOEgbvoqty
N1tfo+UoA872v90JGZSKMWFWhSVjrLAaSeYsGu1mQuQGFyGBicyzAgMBAAE=
-----END RSA PUBLIC KEY-----

... unerbittlich weiter marschieren, und obwohl wir dies erst vor ein paar Befehlen getan haben, drehen wir die Dinge um, damit die Transmogrifikation von RSA zu einfachem alten "öffentlichen Schlüssel" erfolgt:

>openssl rsa -in newclient_rsapublickey.pem -RSAPublicKey_in -pubout
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn/OlFk7vLRQ6dBiNQkvjnhm4p
OYWo+GeAEmU4N1HPZj1dxv704hm80eYc7h12xc7oVcDLBdHByGAGBpQfpjgdPyoz
C/zSqcuU6iBrvzDTpyG1zhIG76KrcjdbX6PlKAPO9r/dCRmUijFhVoUlY6ywGknm
LBrtZkLkBhchgYnMswIDAQAB
-----END PUBLIC KEY-----

... was uns dorthin zurückführt, wo wir begonnen haben. Was haben wir gelernt?

Zusammenfassung: Die Schlüssel sind intern gleich, sie sehen nur anders aus. Ein früherer Kommentar wies darauf hin, 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 Auszeichnung jetzt zu Tode geschlagen.

Für den Fall, dass immer noch ein Funke spark vom Leben übrig ist, lassen Sie uns dies jedoch etwas genauer untersuchen und auf das Zertifikat verweisen, das ursprünglich mit dem privaten RSA-Schlüssel vor langer Zeit generiert wurde, und dabei dessen öffentlichen Schlüssel und Modul untersuchen :

>openssl x509 -in newclient_cert.pem -pubkey -noout -modulus
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn/OlFk7vLRQ6dBiNQkvjnhm4p
OYWo+GeAEmU4N1HPZj1dxv704hm80eYc7h12xc7oVcDLBdHByGAGBpQfpjgdPyoz
C/zSqcuU6iBrvzDTpyG1zhIG76KrcjdbX6PlKAPO9r/dCRmUijFhVoUlY6ywGknm
LBrtZkLkBhchgYnMswIDAQAB
-----END PUBLIC KEY-----
Modulus=
A7FCE94593BBCB450E9D06235092F8E7
866E293985A8F867801265383751CF66
3D5DC6FEF4E219BCD1E61CEE1D76C5CE
E855C0CB05D1C1C8600606941FA6381D
3F2A330BFCD2A9CB94EA206BBF30D3A7
21B5CE1206EFA2AB72375B5FA3E52803
CEF6BFDD0919948A316156852563ACB0
1A49E62C1AED6642E40617218189CCB3

... und sie lebten alle glücklich und glücklich: 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 gekennzeichnet ist. Man kann mit Sicherheit sagen, dass es einen Konsens gibt.

Es gibt kein "RSAPublicKey_out" -Äquivalent-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 DSA-signierten Zertifikat aussehen würde, weiß ich nicht.

Mir ist klar, dass dies nicht die ursprüngliche Frage beantwortet, aber vielleicht bietet es einen nützlichen Hintergrund. Wenn nicht, entschuldige ich mich. Zumindest Dinge, die nicht zu tun sind und Annahmen, die nicht zu treffen sind.

Ohne Zweifel hat man die etwas irritierende Wiederholung des "Schreibens eines RSA-Schlüssels" bemerkt, wenn es nicht so etwas tut. Ich gehe davon aus, dass das RSA-Modul den einfachen, alten öffentlichen Schlüssel als echten RSA-Schlüssel erkennt und deshalb weiterhin 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 Satz von Werten hat (die hilfreichen Namen g, w, q und andere Konsonanten).

Abschließend stelle ich fest, dass es eine Beschwerde in Bezug auf Programmierung und Entwicklung gab. Jetzt hat jeder OpenSSL-Befehl offensichtlich den entsprechenden Code, und wenn man alle Wunder der heutigen OpenSSL-Programmierung erforschen möchte, scheint die Befehlszeile ein vernünftiger Ausgangspunkt zu sein. In diesem speziellen Fall (da ich gerade einen Cygwin verwende) könnte man zunächst\openssl-1.0.2f\apps\rsa.c durchsehen und (vorausgesetzt, man hat eine hohe Toleranz für Makros)\openssl-1.0. 2f\crypto\pem\pem_all.c

10
Lark

Der einzige Unterschied zwischen pub1 und pub2 neben der Kopf-/Fußzeile besteht in der folgenden 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 Algorithmuskennung gemäß diese Antwort .

6
gtrig