ฉันจะเปลี่ยนรูปแบบคีย์สาธารณะทั้งสองรูปแบบได้อย่างไรหนึ่ง“ BEGIN RSA PUBLIC KEY” อีกแบบคือ“ BEGIN PUBLIC KEY”


99

ฉันจะแปลงระหว่างรูปแบบคีย์สาธารณะสองรูปแบบได้อย่างไรรูปแบบหนึ่งคือ:

-----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 เพื่อแก้ไขและคุณควรจะไป!


314

ฉันอยากจะช่วยอธิบายว่าเกิดอะไรขึ้นที่นี่

RSA "คีย์สาธารณะ"ประกอบด้วยตัวเลขสองตัว:

  • โมดูลัส (เช่นหมายเลข 2,048 บิต)
  • เลขชี้กำลัง (ปกติคือ 65,537)

ตัวอย่างการใช้คีย์สาธารณะ RSA ของคุณตัวเลขสองตัวคือ:

  • โมดูลัส : 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
  • เลขชี้กำลัง : 65,537

คำถามจะกลายเป็นว่าเราต้องการเก็บตัวเลขเหล่านี้ไว้ในคอมพิวเตอร์อย่างไร ก่อนอื่นเราแปลงทั้งสองเป็นเลขฐานสิบหก:

  • โมดูลัส : 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

หลังจากนั้นรูปแบบการเข้ารหัสคีย์สาธารณะอื่น ๆ ก็เข้ามา:

  • ดิฟฟี่ - เฮลแมน
  • โค้ง Ellicptic

เมื่อถึงเวลาที่ต้องสร้างมาตรฐานสำหรับวิธีการแสดงพารามิเตอร์ของอัลกอริทึมการเข้ารหัสเหล่านั้นผู้คนก็ใช้แนวคิดเดียวกันกับที่ RSA กำหนดไว้ในตอนแรก:

  • ใช้การเข้ารหัสไบนารี ASN.1
  • base64 มัน
  • ห่อด้วยยัติภังค์ห้าตัว
  • และคำพูด BEGIN PUBLIC KEY

แต่แทนที่จะใช้:

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

พวกเขาตัดสินใจที่จะรวม Object Identifier (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-bytes จะกลายเป็นอักขระสี่ตัว:

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
ลูกศักดิ์สิทธิ์นั่นเป็นข้อมูล! ขอบคุณ. สิ่งนี้ช่วยแก้ปัญหาของฉันกับงูหลามที่คาดหวังเพียง BEGIN RSA PUBLIC KEY แม้ว่าในตัวอย่างล่าสุดของคุณดูเหมือนว่าคุณลืมลบอักขระ 32 ตัว
NullVoxPopuli

คุณใช้เครื่องมืออะไรในการพิมพ์โครงสร้างฐานสิบหกของไฟล์?
Buge

7
@Buge ผมใช้ที่ดีเยี่ยมดีเยี่ยมASN.1 JavaScript ถอดรหัส นั่นและตัวแปลไบนารีเป็นเครื่องมือที่ยอดเยี่ยมสองอย่างที่มีอยู่ในกล่องเครื่องมือของคุณ
Ian Boyd

1
จุดเริ่มต้นของโมดูลัสมีอักขระพิเศษ "1" ควรเริ่มต้นเช่นนี้ ... 297,056,429,939,040,947,991,047,334,197,581,225,628,107,02,573 ... แต่ไม่ใช่สิ่งนี้ ... 297,056,429,939,040,947,991,047,334,197,581,225,628,107,021,573 ของพวกเขา ...
EmpathicSage

2
รุ่น jsFiddle ของ js นอกจากนี้ยังอยู่ในgithub
Ian Boyd

52

ฉันพบว่าเว็บไซต์นี้เป็นคำอธิบายทางเทคนิคที่ดีเกี่ยวกับรูปแบบต่างๆ: https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem

"BEGIN RSA PUBLIC KEY" คือ PKCS # 1 ซึ่งมีได้เฉพาะคีย์ RSA เท่านั้น

"BEGIN PUBLIC KEY" คือ 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 )
Franklin Yu

ไม่ทำงานบน MacOS:unknown option -RSAPublicKey_in
nakajuice

2
@FranklinYu: ใช่ PKCS8 เป็นคีย์ส่วนตัวเท่านั้นและ polarssl ผิดในประเด็นนั้น รูปแบบทั่วไปของคีย์สาธารณะถูกกำหนดโดย X.509 และโดยเฉพาะประเภท SubjectPublicKeyInfo ตามที่ระบุไว้อย่างถูกต้องในคำตอบของ Ian Boyd (ยาว!) ข้อมูลนี้ซ้ำ (สะดวกกว่า) ใน RFC5280 บวกกับ RFC อื่น ๆ ขึ้นอยู่กับอัลกอริทึมโดยมี RSA 'พื้นฐาน' ใน RFC3279
dave_thompson_085

@nakajuice: คุณต้องใช้ OpenSSL เวอร์ชัน 1.0.0 (เปิดตัว 2010) หรือสูงกว่า AIUI Apple หยุดรองรับ OpenSSL บน OS (X) ดังนั้นคุณอาจต้องใช้เวอร์ชันจาก brew หรือคล้ายกัน
dave_thompson_085

สิ่งนี้ทำให้ฉันมีทิศทางที่ถูกต้องสำหรับการแปลงจากรูปแบบ OpenSSH ฉันลงเอยด้วยการใช้ ssh-keygen แบบนี้: ssh-keygen -i -f ~ / .ssh / id_rsa.pub -e -m PKCS8> ~ / .ssh / id_rsa.pub.pem
Bradley Kreider

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

(โอ้ความน่ากลัว! ฉันได้เปิดเผยคีย์ส่วนตัว Meh ... )

ฉันแยกและแสดงคีย์สาธารณะ:

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

... เดินต่อไปอย่างไม่ลดละและแม้ว่าเราจะเพิ่งทำคำสั่งนี้ไปไม่กี่คำสั่งที่ผ่านมาเพื่อให้จุดที่เราพลิกสิ่งต่างๆดังนั้นการแปลงสัญญาณจึงมาจาก RSA เป็น 'คีย์สาธารณะ' แบบเก่า:

>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 ปลอดภัยที่จะบอกว่ามีฉันทามติ

ไม่มีคีย์เวิร์ดที่เทียบเท่า 'RSAPublicKey_out' ในควอดแรนท์ X509 ของกาแลคซี OpenSSL ดังนั้นเราจึงไม่สามารถลองได้แม้ว่าค่าโมดูลัสจะอธิบายว่าเป็น "โมดูลัสคีย์ 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 ของคุณนอกเหนือจากส่วนหัว / ท้ายนี้สตริงเพิ่มเติมใน MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8Apub2: หากคุณลบออกฐาน 64 จะเหมือนกับใน pub1

สตริงพิเศษสอดคล้องกับตัวระบุอัลกอริทึมตามคำตอบนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.