Jak mogę zmienić między dwoma stylami formatu klucza publicznego, jednym „BEGIN RSA PUBLIC KEY”, a drugim „BEGIN PUBLIC KEY”

99

Jak mogę dokonać transformacji między dwoma stylami formatu klucza publicznego, jeden format to:

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

inny format to:

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

na przykład wygenerowałem parę id_rsa / id_rsa.pub za pomocą polecenia ssh-keygen, obliczyłem klucz publiczny z id_rsa używając:

openssl rsa -in id_rsa -pubout -out pub2 

potem znowu obliczyłem klucz publiczny z id_rsa.pub używając:

ssh-keygen -f id_rsa.pub -e -m pem > pub1

zawartość to pub1 to:

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

a zawartość pub2 to:

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

Zgodnie z moim zrozumieniem pub1 i pub2 zawierają te same informacje o kluczu publicznym, ale są w innym formacie, zastanawiam się, jak mogę zmienić między tymi dwoma formatami? Czy ktoś może mi pokazać zwięzłe wprowadzenie do formatów holowania?

welkinwalker
źródło
Stack Overflow to witryna zawierająca pytania dotyczące programowania i programowania. To pytanie wydaje się być niezwiązane z tematem, ponieważ nie dotyczy programowania ani programowania. Zobacz, o jakie tematy mogę zapytać w Centrum pomocy. Być może lepszym miejscem do zadawania pytań będzie Super User lub Unix & Linux Stack Exchange .
jww

Odpowiedzi:

12

Korzystanie z phpseclib, czystej implementacji PHP RSA ...

<?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);

Wydaje się, że elementy zakodowane w base64 pasują do siebie, mimo że w nagłówku jest napisane BEGIN PUBLIC KEY, a nie BEGIN RSA PUBLIC KEY. Więc może po prostu użyj str_replace, aby to naprawić i powinieneś być gotowy!


źródło
314

Chciałem pomóc wyjaśnić, co się tutaj dzieje.

„Klucz publiczny” RSA składa się z dwóch liczb:

  • moduł (np. 2048 bitów)
  • wykładnik (zwykle 65,537)

Na przykładzie klucza publicznego RSA te dwie liczby to:

  • Moduł : 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
  • Wykładnik : 65,537

Powstaje zatem pytanie, w jaki sposób chcemy przechowywać te liczby w komputerze. Najpierw konwertujemy oba na szesnastkowe:

  • Moduł : EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65
  • Wykładnik : 010001

RSA wynalazł pierwszy format

RSA jako pierwszy wymyślił format:

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

Zdecydowali się użyć odmiany DER standardu kodowania binarnego ASN.1 do reprezentowania dwóch liczb [1] :

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

Ostateczne kodowanie binarne w ASN.1 to:

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

Jeśli następnie uruchomisz wszystkie te bajty razem i zakodujesz je Base64, otrzymasz:

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

Następnie laboratoria RSA powiedziały, że dodaj nagłówek i zwiastun:

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

Pięć łączników i słowa BEGIN RSA PUBLIC KEY. To jest Twój klucz publiczny PEM DER ASN.1 PKCS # 1 RSA

  • PEM: synonim base64
  • DER: odmiana kodowania ASN.1
  • ASN.1: stosowany schemat kodowania binarnego
  • PKCS # 1: Formalna specyfikacja, która nakazuje reprezentowanie klucza publicznego jako struktury składającej się z modułu, po którym następuje wykładnik
  • Klucz publiczny RSA: używany algorytm klucza publicznego

Nie tylko RSA

Potem pojawiły się inne formy kryptografii klucza publicznego:

  • Diffie-Hellman
  • Krzywa eliptyczna

Kiedy nadszedł czas, aby stworzyć standard reprezentacji parametrów tych algorytmów szyfrowania, ludzie przyjęli wiele z tych samych pomysłów, które pierwotnie zdefiniowało RSA:

  • użyj kodowania binarnego ASN.1
  • base64 it
  • zawiń go pięcioma łącznikami
  • i słowa BEGIN PUBLIC KEY

Ale zamiast używać:

  • -----BEGIN RSA PUBLIC KEY-----
  • -----BEGIN DH PUBLIC KEY-----
  • -----BEGIN EC PUBLIC KEY-----

Postanowili zamiast tego dołączyć identyfikator obiektu (OID) tego, co ma nastąpić. W przypadku klucza publicznego RSA jest to:

  • RSA PKCS # 1 :1.2.840.113549.1.1.1

Więc dla klucza publicznego RSA był to zasadniczo:

public struct RSAPublicKey {
   INTEGER modulus,
   INTEGER publicExponent 
}

Teraz stworzyli SubjectPublicKeyInfo, który jest w zasadzie:

public struct SubjectPublicKeyInfo {
   AlgorithmIdentifier algorithm,
   RSAPublicKey subjectPublicKey
}

W rzeczywistości definicja DER ASN.1 to:

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
        }
}

To daje ASN.1 z:

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): EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65
         INTEGER (24 bit): 010001

Ostateczne kodowanie binarne w ASN.1 to:

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

I tak jak poprzednio, bierzesz wszystkie te bajty, koduje je Base64, kończysz na drugim przykładzie:

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

Dodaj nieco inny nagłówek i zwiastun, a otrzymasz:

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

A to jest Twój klucz publiczny X.509 SubjectPublicKeyInfo / OpenSSL PEM [2] .

Zrób to dobrze lub zhakuj

Teraz, gdy wiesz, że kodowanie nie jest magiczne, możesz napisać wszystkie elementy potrzebne do przeanalizowania modułu i wykładnika RSA. Lub możesz rozpoznać, że pierwsze 24 bajty to po prostu dodane nowe rzeczy w stosunku do oryginalnego standardu PKCS # 1

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)
|  |  ...

Te pierwsze 24 bajty to „nowe” dodane rzeczy:

30 82 01 22 30 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05 00 03 82 01 0F 00

A dzięki niezwykłemu zbiegowi okoliczności i powodzenia:

24 bajty odpowiadają dokładnie 32 znakom zakodowanym w formacie base64

Ponieważ w Base64: 3 bajty to cztery znaki:

30 82 01  22 30 0D  06 09 2A  86 48 86  F7 0D 01  01 01 05  00 03 82  01 0F 00
\______/  \______/  \______/  \______/  \______/  \______/  \______/  \______/
    |         |         |         |         |         |         |         |
  MIIB      IjAN      Bgkq      hkiG      9w0B      AQEF      AAOC      AQ8A

Oznacza to, że jeśli weźmiesz drugi klucz publiczny X.509, pierwsze 32 znaki odpowiadają tylko nowo dodanym elementom:

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

Jeśli usuniesz pierwsze 32 znaki i zmienisz je na 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-----

Masz dokładnie to, czego chciałeś - starszy RSA PUBLIC KEYformat.

Ian Boyd
źródło
29
Święte bale, to było pouczające! Dziękuję Ci. To rozwiązało mój problem z facetem od Pythona, który oczekiwał tylko BEGIN RSA PUBLIC KEY. Chociaż w ostatnim przykładzie wygląda na to, że zapomniałeś usunąć 32 znaki.
NullVoxPopuli
Jakiego narzędzia użyłeś do wydrukowania szesnastkowej struktury plików?
Buge
7
@Buge Użyłem znakomitego dekodera ASN.1 JavaScript . To i TRANSLATOR, BINARY to dwa doskonałe narzędzia, które możesz mieć w swoim zestawie sztuczek.
Ian Boyd
1
Początek modułu ma dodatkowy znak „1”. Powinno zacząć się tak ... 297,056,429,939,040,947,991,047,334,197,581,225,628,107,02,573 ... ale NIE to ... 297,056,429,939,040,947,991,047,334,197,581,225,628,107,021,573 ... nadzieja, która pomaga komuś w złości na ich konwersję heksów.
EmpathicSage
2
jsFiddle wersja ASN.1 js . Jest również na githubie
Ian Boyd
52

Uważam, że ta strona internetowa jest dobrym technicznym wyjaśnieniem różnych formatów: https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem

„BEGIN RSA PUBLIC KEY” to PKCS # 1, który może zawierać tylko klucze RSA.

„BEGIN PUBLIC KEY” to PKCS # 8, który może zawierać różne formaty.

Jeśli chcesz je po prostu przekonwertować za pomocą wiersza poleceń, "openssl rsa" jest do tego dobra.

Aby przekonwertować z PKCS # 8 na PKCS # 1:

openssl rsa -pubin -in <filename> -RSAPublicKey_out

Aby przekonwertować z PKCS # 1 na PKCS # 8:

openssl rsa -RSAPublicKey_in -in <filename> -pubout
Esme Povirk
źródło
2
Nie mogę znaleźć nic o kluczu publicznym w PKCS # 8 ( RFC 5208 ).
Franklin Yu
Nie działa na MacOS:unknown option -RSAPublicKey_in
nakajuice
2
@FranklinYu: tak PKCS8 jest tylko prywatny i polarssl nie ma racji w tej kwestii. Ogólna forma publickey jest zdefiniowana przez X.509, a konkretnie typ SubjectPublicKeyInfo, jak poprawnie podano w (długiej!) Odpowiedzi Iana Boyda; ta informacja jest (wygodniej) powielana w RFC5280 oraz w innych dokumentach RFC w zależności od algorytmu, z „podstawowym” RSA w RFC3279.
dave_thompson_085
@nakajuice: Potrzebujesz OpenSSL w wersji 1.0.0 (wydanej 2010) lub nowszej. AIUI Apple przestało wspierać OpenSSL w systemie OS (X), więc możesz potrzebować wersji z brew lub podobnej.
dave_thompson_085
To doprowadziło mnie do właściwego kierunku konwersji z formatu OpenSSH. Skończyło się na tym, że użyłem ssh-keygen w następujący sposób: ssh-keygen -i -f ~ / .ssh / id_rsa.pub -e -m PKCS8> ~ / .ssh / id_rsa.pub.pem
Bradley Kreider
13

Chociaż powyższe komentarze dotyczące 32-bajtowych nagłówków, formatów OID i tym podobnych są interesujące, osobiście nie widzę tego samego zachowania, zakładając, że rozumiem. Pomyślałem, że pomocne może być dalsze zbadanie tego, co większość może uważać za nadmierne szczegóły. Nie ma nic lepszego niż nadmiar.

Na początek utworzyłem klucz prywatny RSA i sprawdziłem go:

>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-----

(Och, okropności! Ujawniłem klucz prywatny. Meh ...)

Wyodrębniam i wyświetlam jego klucz publiczny:

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

Tak się składa, że ​​istnieje inny parametr wyjściowy klucza publicznego (jak wspomniano we wcześniejszym komentarzu). Wyodrębniam i wyświetlam klucz publiczny za pomocą tego słowa kluczowego:

>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-----

Dobrze, dobrze. Te dwie wartości klucza publicznego nie są takie same, chociaż pochodzą z tego samego klucza prywatnego. A może są takie same? Wycinam i wklejam dwa ciągi kluczy publicznych do ich własnych plików, a następnie sprawdzam każdy z nich:

>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-----

The „pubin” mówi RSA, że to naprawdę jest ma być klucz publiczny i nie skarżą się, że nie jest to klucz prywatny.

Teraz bierzemy publiczny klucz RSA, wyświetlamy moduł i przekształcamy go w zwykły stary „klucz publiczny” (znowu musimy powiedzieć, że dane wejściowe są kluczem publicznym):

>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-----

Ten sam moduł i ta sama wartość „klucza publicznego”. Aby uczynić rzeczy bardziej interesującymi (w każdym razie dla mnie), kiedy dodamy słowo kluczowe RSAPublicKey_out , otrzymujemy:

>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-----

... i kiedy transmogryfikujemy zwykły stary „klucz publiczny” w klucz publiczny RSA:

>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-----

... maszerujesz nieubłaganie i chociaż zrobiliśmy to kilka poleceń temu, aby podkreślić, że odwrócimy rzeczy, aby transmogryfikacja przebiegała z RSA do zwykłego starego „klucza publicznego”:

>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-----

... co prowadzi nas z powrotem do miejsca, w którym zaczęliśmy. Czego się nauczyliśmy?

Podsumowanie: klucze wewnętrznie są takie same, po prostu wyglądają inaczej. Wcześniejszy komentarz wskazywał, że format klucza RSA został zdefiniowany w PKCS # 1, a zwykły stary format „klucza publicznego” został zdefiniowany w PKCS # 8. Jednak edycja jednego formularza nie zmienia go w drugi. Mam nadzieję, że pokonałem to wyróżnienie na śmierć.

Jednak na wypadek, gdyby pozostała jeszcze iskierka życia, zacznijmy trochę więcej i odwołajmy się do certyfikatu, który został pierwotnie wygenerowany z kluczem prywatnym RSA tak dawno temu, badając jego klucz publiczny i moduł:

>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

... i wszyscy żyli długo i szczęśliwie: certyfikat ma taką samą wartość modułu, jak klucz publiczny RSA, klucz prywatny RSA i zwykły stary „klucz publiczny”. Certyfikat zawiera tę samą zwykłą wartość „klucza publicznego”, którą widzieliśmy wcześniej, chociaż został podpisany plikiem oznaczonym jako klucz prywatny RSA. Można śmiało powiedzieć, że istnieje konsensus.

W kwadrancie X509 galaktyki OpenSSL nie ma odpowiednika słowa kluczowego „RSAPublicKey_out”, więc nie możemy tego wypróbować, chociaż wartość modułu jest opisana jako „kluczowy moduł RSA”, który, jak przypuszczam, jest tak blisko, jak to tylko możliwe.

Jak to wszystko wyglądałoby z certyfikatem podpisanym przez DSA, nie wiem.

Zdaję sobie sprawę, że to nie odpowiada na pierwotne pytanie, ale być może dostarcza przydatnych informacji. Jeśli nie, przepraszam. Przynajmniej rzeczy, których nie należy robić i założenia, których nie należy robić.

Bez wątpienia można zauważyć nieco irytujące powtarzanie się „pisania klucza RSA”, kiedy nie robi się czegoś takiego. Zakładam, że chodziło o to, że moduł rsa rozpoznaje zwykły stary klucz publiczny jako prawdziwy klucz RSA, i dlatego ciągle używa „klucza RSA” (a ponadto jest to w końcu moduł rsa). Jeśli dobrze pamiętam, ogólna struktura EVP_PKEY ma unię dla wszystkich typów kluczy, przy czym każdy typ klucza ma swój własny specjalny zestaw wartości (pomocna nazwa g, w, q i inne spółgłoski).

Podsumowując, zauważam, że była skarga dotycząca programowania i rozwoju; teraz każde polecenie OpenSSL ma oczywiście odpowiadający mu kod, a jeśli ktoś chciałby zbadać wszystkie cuda, którymi jest dziś programowanie OpenSSL, wiersz poleceń wydaje się rozsądnym miejscem do rozpoczęcia. W tym konkretnym przypadku (ponieważ w tej chwili używam najnowszego cygwina) można zacząć od przejrzenia \ openssl-1.0.2f \ apps \ rsa.c i (biorąc pod uwagę, że ma on dużą tolerancję na makra) \ openssl-1.0. 2f \ crypto \ pem \ pem_all.c

Skowronek
źródło
8

Różnica tylko między pub1 i pub2 oprócz nagłówka / stopki, jest to dodatkowy ciąg w pub2: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A. Jeśli to usuniesz, Base 64 będzie identyczny z tym w pub1.

Dodatkowy ciąg odpowiada identyfikatorowi algorytmu zgodnie z tą odpowiedzią .

gtrig
źródło