Як я можу трансформувати між двома стилями формату відкритого ключа, один “ПОЧАТИ РЕСПУБЛІЧНИЙ КЛЮЧ”, інший - “ПОЧАТИ ПУБЛІЧНИЙ КЛЮЧ”


97

Як я можу перетворити між двома стилями формат відкритого ключа, один із таких форматів:

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

інший формат:

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

наприклад, я створив пару id_rsa / id_rsa.pub за допомогою команди ssh-keygen, я розрахував відкритий ключ з id_rsa, використовуючи:

openssl rsa -in id_rsa -pubout -out pub2 

потім я знову розрахував відкритий ключ з id_rsa.pub, використовуючи:

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

вміст pub1:

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

а вміст pub2:

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

Згідно з моїм розумінням, pub1 та pub2 містять одну і ту ж інформацію про відкритий ключ, але вони в іншому форматі. Цікаво, як я можу трансформуватися між двома форматами? Хто-небудь може показати мені короткий вступ щодо форматів буксирування?


Stack Overflow - це сайт для питань програмування та розробки. Здається, це питання не є темою, оскільки мова не йде про програмування чи розробку. Подивіться, які теми я можу запитати тут, у довідковому центрі. Можливо, кращим місцем для запитання буде Super User або Unix & Linux Stack Exchange .
jww

Відповіді:


12

Використовуючи phpseclib, чиста реалізація 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);

Матеріали, закодовані base64, схоже, збігаються, хоча в заголовку написано BEGIN PUBLIC KEY, а не BEGIN RSA PUBLIC KEY. Тож, можливо, просто використовуйте str_replace, щоб це виправити, і вам слід бути готовим!


312

Я хотів допомогти пояснити, що тут відбувається.

"Відкритий ключ" RSA складається з двох номерів:

  • модуль (наприклад, 2048-бітове число)
  • показник ступеня (зазвичай 65 537)

На прикладі вашого відкритого ключа RSA є два числа:

  • Модуль : 297 056 429 939 040 947 991 047 334 197 981 25528287 0721573 849,359 042 679 698 093 131 318, 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
  • Показник : 65 537

Тоді виникає питання, як ми хочемо зберігати ці номери в комп’ютері. Спочатку ми перетворюємо обидва в шістнадцяткові:

  • Modulus : EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65
  • Показник : 010001

RSA винайшов перший формат

Спочатку RSA винайшов формат:

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

Вони вирішили використовувати аромат DER стандарту двійкового кодування ASN.1 для представлення двох чисел [1] :

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

Остаточне двійкове кодування в ASN.1:

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

Якщо ви потім запустите всі ці байти разом і закодуєте Base64, ви отримаєте:

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

Потім лабораторії RSA сказали, що додають заголовок та трейлер:

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

П’ять дефісів і слова BEGIN RSA PUBLIC KEY. Це ваш відкритий ключ PEM DER ASN.1 PKCS # 1 RSA

  • PEM: синонім base64
  • DER: смак кодування ASN.1
  • ASN.1: використана схема двійкового кодування
  • PKCS # 1: Формальна специфікація, яка диктує представлення відкритого ключа як структури, що складається з модуля з наступним показником
  • Відкритий ключ RSA: використовується алгоритм відкритого ключа

Не тільки RSA

Після цього з’явились інші форми криптографії відкритого ключа:

  • Діффі-Хеллман
  • Еліптична крива

Коли прийшов час створити стандарт, як відображати параметри цих алгоритмів шифрування, люди прийняли багато тих самих ідей, які спочатку визначав RSA:

  • використовувати двійкове кодування ASN.1
  • base64 це
  • оберніть його п’ятьма дефісами
  • і слова BEGIN PUBLIC KEY

Але замість використання:

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

Натомість вони вирішили включити ідентифікатор об’єкта (OID) того, що слід слідувати. У випадку відкритого ключа RSA, це:

  • RSA PKCS # 1 :1.2.840.113549.1.1.1

Отже, для відкритого ключа RSA це було по суті:

public struct RSAPublicKey {
   INTEGER modulus,
   INTEGER publicExponent 
}

Зараз вони створили SubjectPublicKeyInfo, який в основному є:

public struct SubjectPublicKeyInfo {
   AlgorithmIdentifier algorithm,
   RSAPublicKey subjectPublicKey
}

У фактичному визначенні DER ASN.1 є:

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

Це дає вам ASN.1 із:

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

Остаточне двійкове кодування в ASN.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)
|  |  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

І як і раніше, ви берете всі ці байти, Base64 їх кодує, і ви отримуєте свій другий приклад:

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

Додайте дещо інший заголовок і трейлер, і ви отримаєте:

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

І це ваш відкритий ключ X.509 SubjectPublicKeyInfo / OpenSSL PEM [2] .

Зробіть це правильно, або зламайте

Тепер, коли ви знаєте, що кодування не є магією, ви можете записати всі фрагменти, необхідні для синтаксичного аналізу модуля RSA та експоненти. Або ви можете усвідомити, що перші 24 байти просто додали нові матеріали на додаток до оригінального стандарту 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)
|  |  ...

Ці перші 24-байтові додані "нові" матеріали:

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

І завдяки надзвичайному збігу фортуни та удачі:

24 байти відповідають точно 32 кодованим символам base64

Оскільки в Base64: 3-байти стають чотирма символами:

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

Це означає, що якщо ви берете другий відкритий ключ X.509, перші 32 символи відповідають лише нещодавно доданим матеріалам:

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

Якщо видалити перші 32 символи та змінити їх на 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-----

У вас є саме те, що ви хотіли - старіший RSA PUBLIC KEYформат.


29
Святі кульки, це було інформативно! Дякую. Це вирішило мою проблему з хлопцем-пітоном, який очікував лише ПОЧАТИ ПУБЛІЧНИЙ КЛЮЧ RSA. Хоча, у вашому останньому прикладі, схоже, ви забули видалити 32 символи.
NullVoxPopuli

Яким інструментом ви роздруковували шістнадцяткову структуру файлів?
Баге

7
@Buge Я використовував чудовий, відмінний, декодер JavaScript ASN.1 . Це та ПЕРЕКЛАДНИК, BINARY - це два чудові інструменти, які потрібно мати у наборі прийомів.
Ян Бойд

1
Початок модуля має додатковий символ "1". Все повинно починатися так ... 297 056 429 939 040 947 991 047 334 197 981 825 256 287 107 022 573 ... але НЕ це ... 297 056 429 939 040 947 991 047 334 197 981 825 256 287 0721 553 ... сподівання, що допомагає комусь злитися на їх шестнадцатеричное перетворення.
EmpathicSage


51

Я знайшов цей веб-сайт хорошим технічним поясненням різних форматів: https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem

"ПОЧАТИ ПУБЛІЧНИЙ КЛЮЧ RSA" - PKCS №1, який може містити лише ключі RSA.

"ПОЧАТИ ПУБЛІЧНИЙ КЛЮЧ" - PKCS № 8, який може містити різні формати.

Якщо ви просто хочете перетворити їх за допомогою командного рядка, "openssl rsa" добре для цього підійде.

Щоб перетворити з PKCS # 8 на PKCS # 1:

openssl rsa -pubin -in <filename> -RSAPublicKey_out

Щоб перетворити з PKCS # 1 на PKCS # 8:

openssl rsa -RSAPublicKey_in -in <filename> -pubout

2
Я не можу знайти нічого про відкритий ключ у PKCS # 8 ( RFC 5208 ).
Франклін Ю

Не працює на MacOS:unknown option -RSAPublicKey_in
nakajuice

2
@FranklinYu: так, PKCS8 - це лише приватний ключ, і polarssl помиляється в цьому питанні. Загальна форма відкритого ключа визначається X.509, а саме тип SubjectPublicKeyInfo, як правильно зазначено у відповіді Яна Бойда (довгий!); ця інформація (зручніше) дублюється у RFC5280 плюс інші RFC, залежно від алгоритму, із "базовою" RSA у RFC3279.
dave_thompson_085

@nakajuice: Вам потрібен OpenSSL версії 1.0.0 (випущений 2010) або вище. AIUI Apple припинила підтримку OpenSSL в ОС (X), тому вам може знадобитися версія від brew або подібної.
dave_thompson_085

Це підвело мене до правильного напрямку перетворення з формату OpenSSH. У підсумку я використав ssh-keygen так: ssh-keygen -i -f ~ / .ssh / id_rsa.pub -e -m PKCS8> ~ / .ssh / id_rsa.pub.pem
Бредлі

13

Хоча наведені вище коментарі щодо 32-байтових заголовків, форматів OID та подібних цікаві, я особисто не бачу такої ж поведінки, припускаючи, що я зрозумів суть. Я вважав, що може бути корисним вивчити це далі, на думку більшості надмірних деталей. Ніщо не перевищує, як надлишок.

Для початку я створив приватний ключ RSA і перевірив його:

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

(О, жахи! Я викрив приватний ключ. Ме ...)

Я витягаю та відображаю його відкритий ключ:

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

Так трапляється, є інший вихідний параметр відкритого ключа (як уже згадувалося в попередньому коментарі). Я витягаю та відображаю відкритий ключ, використовуючи це ключове слово:

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

Добре. Ці два значення відкритого ключа не є однаковими, хоча походять від одного і того ж приватного ключа. Або вони однакові? Я вирізаю та вставляю два рядки відкритих ключів у власні файли, а потім перевіряю модуль на кожному:

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

«Pubin» говорить ПДС , що це на самому справі це повинен бути відкритий ключ, і не скаржаться , що це не закритий ключ.

Тепер ми беремо відкритий ключ RSA, відображаємо модуль і перетворюємо його на звичайний старий "відкритий ключ" (знову ж таки, ми повинні сказати йому, що вхід є відкритим ключем):

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

Відображається той самий модуль і одне і те ж значення „відкритого ключа”. Щоб зробити речі цікавішими (у будь-якому випадку для мене), коли ми беремо ключове слово RSAPublicKey_out, отримуємо:

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

... і коли ми перетворюємо звичайний старий «відкритий ключ» на відкритий ключ 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-----

.

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

... що повертає нас туди, звідки ми почали. Що ми дізналися?

Короткий зміст: клавіші всередині однакові, вони просто виглядають по-різному. У попередньому коментарі зазначалося, що формат ключа RSA був визначений у PKCS # 1, а звичайний старий формат "відкритого ключа" був визначений у PKCS # 8. Однак редагування однієї форми не перетворює її на іншу. Сподіваюся, я зараз перебив цю відзнаку до смерті.

Якщо все-таки залишилася іскра життя, давайте ще трохи бичувати і посилатися на сертифікат, який спочатку був створений із закритим ключем RSA так давно, вивчивши його відкритий ключ і модуль:

>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

... і всі вони жили довго і щасливо: сертифікат має таке саме значення модуля, як відкритий ключ RSA, приватний ключ RSA та звичайний старий «відкритий ключ». Сертифікат містить те саме звичайне старе значення «відкритого ключа», що ми бачили раніше, хоча воно було підписане файлом, позначеним як закритий ключ RSA. Можна з упевненістю сказати, що є консенсус.

У квадранті X509 галактики OpenSSL немає еквівалентного ключового слова 'RSAPublicKey_out', тому ми не можемо спробувати це, хоча значення модуля описується як "модуль ключа RSA", який, на мою думку, наближається до нас.

Як би все це виглядало із сертифікатом, підписаним DSA, я не знаю.

Я усвідомлюю, що це не дає відповіді на вихідне питання, але, можливо, воно дає деяку корисну довідку. Якщо ні, мої вибачення. Принаймні, речей, яких не можна робити, а припущень - не робити.

Без сумніву, хтось зауважив трохи дратує повторення "написання ключа RSA", коли він не робить нічого подібного. Я припускаю, що мається на увазі те, що модуль rsa розпізнає звичайний старий відкритий ключ як справжній ключ RSA, і саме тому він продовжує покладатися на "ключ RSA" (плюс, зрештою, це модуль rsa). Якщо я правильно згадую, загальна структура EVP_PKEY має об’єднання для всіх типів ключів, причому кожен тип ключів має свій спеціальний набір значень (корисно названі g, w, q та інші приголосні).

На закінчення зазначу, що була скарга щодо програмування та розробки; Зараз кожна команда OpenSSL, очевидно, має відповідний код, і якщо хочеться дослідити всі чудеса, які сьогодні є програмуванням OpenSSL, командний рядок здається розумним місцем для початку. У цьому конкретному випадку (оскільки я зараз використовую нещодавній cygwin) можна почати з перегляду \ openssl-1.0.2f \ apps \ rsa.c та (з урахуванням того, що один з них має високий допуск до макросів) \ openssl-1.0. 2f \ crypto \ pem \ pem_all.c


8

Єдина відмінність між pub1 і pub2, крім верхнього / нижнього колонтитула, ця додаткова рядок в pub2: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A. Якщо видалити це, Base 64 ідентичний тому, що в pub1.

Додатковий рядок відповідає ідентифікатору алгоритму відповідно до цієї відповіді .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.