Làm cách nào để tôi có thể chuyển đổi giữa hai kiểu định dạng khóa công khai, một kiểu “BẮT ĐẦU KHÓA CÔNG KHAI RSA”, kiểu còn lại là “BẮT ĐẦU KHÓA CÔNG KHAI”


99

Làm cách nào để tôi có thể chuyển đổi giữa hai kiểu định dạng khóa công khai, một định dạng là:

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

định dạng khác là:

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

ví dụ: tôi đã tạo cặp id_rsa / id_rsa.pub bằng lệnh ssh-keygen, tôi đã tính khóa công khai từ id_rsa bằng cách sử dụng:

openssl rsa -in id_rsa -pubout -out pub2 

sau đó, một lần nữa tôi tính khóa công khai từ id_rsa.pub bằng cách sử dụng:

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

nội dung là pub1 là:

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

và nội dung của pub2 là:

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

Theo hiểu biết của tôi thì pub1 và pub2 chứa thông tin khóa công khai giống nhau, nhưng chúng ở định dạng khác nhau, tôi tự hỏi làm thế nào tôi có thể chuyển đổi giữa hai định dạng? Bất cứ ai có thể chỉ cho tôi một số giới thiệu ngắn gọn về các định dạng kéo được không?


Stack Overflow là một trang dành cho các câu hỏi về lập trình và phát triển. Câu hỏi này có vẻ lạc đề vì nó không phải về lập trình hay phát triển. Xem những chủ đề tôi có thể hỏi tại đây trong Trung tâm trợ giúp. Có lẽ Super User hoặc Unix & Linux Stack Exchange sẽ là nơi tốt hơn để hỏi.
jww

Câu trả lời:


12

Sử dụng phpseclib, một triển khai PHP RSA thuần túy ...

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

Nội dung được mã hóa base64 dường như khớp ngay cả khi tiêu đề cho biết BẮT ĐẦU KHÓA CÔNG KHAI chứ không phải BẮT ĐẦU KHÓA CÔNG KHAI RSA. Vì vậy, có lẽ chỉ cần sử dụng str_replace để khắc phục điều đó và bạn nên thực hiện!


314

Tôi muốn giúp giải thích những gì đang xảy ra ở đây.

RSA "Khóa công khai" bao gồm hai số:

  • môđun (ví dụ: số bit 2.048)
  • số mũ (thường là 65,537)

Sử dụng khóa công khai RSA của bạn làm ví dụ, hai con số là:

  • Mô-đun : 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
  • Số mũ : 65,537

Sau đó, câu hỏi trở thành làm cách nào chúng ta muốn lưu trữ những con số này trong máy tính. Đầu tiên, chúng tôi chuyển đổi cả hai sang hệ thập lục phân:

  • Modulus : EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65
  • Số mũ : 010001

RSA đã phát minh ra định dạng đầu tiên

RSA đầu tiên đã phát minh ra một định dạng:

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

Họ đã chọn sử dụng hương vị DER của tiêu chuẩn mã hóa nhị phân ASN.1 để biểu diễn hai số [1] :

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

Mã hóa nhị phân cuối cùng trong ASN.1 là:

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

Nếu sau đó bạn chạy tất cả các byte đó cùng nhau và Base64 mã hóa nó, bạn sẽ nhận được:

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

Phòng thí nghiệm RSA sau đó cho biết thêm tiêu đề và đoạn giới thiệu:

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

Năm dấu gạch nối, và các từ BEGIN RSA PUBLIC KEY. Đó là Khóa công khai PEM DER ASN.1 PKCS # 1 RSA của bạn

  • PEM: từ đồng nghĩa với base64
  • DER: một hương vị của mã hóa ASN.1
  • ASN.1: lược đồ mã hóa nhị phân được sử dụng
  • PKCS # 1: Đặc điểm kỹ thuật chính thức ra lệnh đại diện cho khóa công khai dưới dạng cấu trúc bao gồm mô-đun theo sau là số mũ
  • Khóa công khai RSA: thuật toán khóa công khai đang được sử dụng

Không chỉ RSA

Sau đó, các dạng mật mã khóa công khai khác ra đời:

  • Diffie-Hellman
  • Đường cong hình nang

Khi đến lúc tạo ra một tiêu chuẩn về cách biểu diễn các tham số của các thuật toán mã hóa đó, mọi người đã áp dụng rất nhiều ý tưởng giống như RSA đã xác định ban đầu:

  • sử dụng mã hóa nhị phân ASN.1
  • base64 nó
  • bọc nó bằng năm dấu gạch nối
  • và những từ BEGIN PUBLIC KEY

Nhưng thay vì sử dụng:

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

Thay vào đó, họ đã quyết định bao gồm Mã định danh đối tượng (OID) của những gì cần tuân theo. Trong trường hợp khóa công khai RSA, đó là:

  • RSA PKCS # 1 :1.2.840.113549.1.1.1

Vì vậy, đối với khóa công khai RSA về cơ bản là:

public struct RSAPublicKey {
   INTEGER modulus,
   INTEGER publicExponent 
}

Bây giờ họ đã tạo SubjectPublicKeyInfo về cơ bản:

public struct SubjectPublicKeyInfo {
   AlgorithmIdentifier algorithm,
   RSAPublicKey subjectPublicKey
}

Trong định nghĩa DER ASN.1 thực tế là:

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

Điều đó cung cấp cho bạn ASN.1 của:

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

Mã hóa nhị phân cuối cùng trong ASN.1 là:

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

Và như trước đây, bạn lấy tất cả các byte đó, Base64 mã hóa chúng, bạn kết thúc với ví dụ thứ hai của mình:

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

Thêm tiêu đề và đoạn giới thiệu hơi khác, và bạn nhận được:

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

Và đây là khóa công khai X.509 SubjectPublicKeyInfo / OpenSSL PEM [2] của bạn .

Làm đúng, hoặc hack nó

Bây giờ bạn biết rằng mã hóa không phải là phép thuật, bạn có thể viết tất cả các phần cần thiết để phân tích cú pháp mô-đun RSA và số mũ. Hoặc bạn có thể nhận ra rằng 24 byte đầu tiên chỉ là nội dung mới được thêm vào bên trên tiêu chuẩn PKCS # 1 ban đầu

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 byte đầu tiên đó là nội dung "mới" được thêm vào:

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

Và do một sự trùng hợp ngẫu nhiên về tài lộc và may mắn:

24 byte tương ứng chính xác với 32 ký tự được mã hóa base64

Bởi vì trong Base64: 3-byte trở thành bốn ký tự:

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

Điều đó có nghĩa là nếu bạn sử dụng khóa công khai X.509 thứ hai của mình, 32 ký tự đầu tiên chỉ tương ứng với nội dung mới được thêm vào:

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

Nếu bạn xóa 32 ký tự đầu tiên và thay đổi nó thành BẮT ĐẦU KHÓA CÔNG KHAI 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-----

Bạn có chính xác những gì bạn muốn - RSA PUBLIC KEYđịnh dạng cũ hơn .


29
Quả bóng thánh, đó là thông tin! cảm ơn bạn. Điều này đã giải quyết được sự cố của tôi với một anh chàng python chỉ mong đợi BẮT ĐẦU KHÓA CÔNG KHAI RSA. Mặc dù vậy, trong ví dụ cuối cùng của bạn, có vẻ như bạn đã quên xóa 32 ký tự.
NullVoxPopuli

Bạn đã sử dụng công cụ nào để in ra cấu trúc hex của tệp?
Buge

7
@Buge Tôi đã sử dụng bộ giải mã JavaScript ASN.1 xuất sắc, tuyệt vời . Đó và TRANSLATOR, BINARY là hai công cụ tuyệt vời cần có trong hộp công cụ thủ thuật của bạn.
Ian Boyd

1
Phần bắt đầu của mô-đun có thêm một ký tự "1". Nó sẽ bắt đầu như thế này ... 297.056.429.939.040.947.991.047.334.197.581.225.628.107,02.573 ... nhưng KHÔNG phải điều này ... 297.056.429.939.040.947.991.047.334.197.581.225.628.107.021.573 ... hy vọng điều đó sẽ giúp một số người không tức giận với chuyển đổi hex của họ.
EmpathicSage


52

Tôi thấy trang web này là một giải thích kỹ thuật tốt về các định dạng khác nhau: https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem

"BEGIN RSA PUBLIC KEY" là PKCS # 1, chỉ có thể chứa các khóa RSA.

"BEGIN PUBLIC KEY" là PKCS # 8, có thể chứa nhiều định dạng.

Nếu bạn chỉ muốn chuyển đổi chúng bằng dòng lệnh, thì "openssl rsa" là tốt cho việc này.

Để chuyển đổi từ PKCS # 8 sang PKCS # 1:

openssl rsa -pubin -in <filename> -RSAPublicKey_out

Để chuyển đổi từ PKCS # 1 sang PKCS # 8:

openssl rsa -RSAPublicKey_in -in <filename> -pubout

2
Tôi không thể tìm thấy bất cứ điều gì về khóa công khai trong PKCS # 8 ( RFC 5208 ).
Franklin Yu

Không hoạt động trên MacOS:unknown option -RSAPublicKey_in
nakajuice Ngày

2
@FranklinYu: có PKCS8 chỉ là privatekey và polarssl đã sai về điểm đó. Dạng chung của khóa công khai được xác định bởi X.509 và cụ thể là kiểu SubjectPublicKeyInfo, như được nêu chính xác trong câu trả lời (long!) Của Ian Boyd; thông tin này được sao chép (thuận tiện hơn) trong RFC5280 cộng với các RFC khác tùy thuộc vào thuật toán, với RSA 'cơ bản' trong RFC3279.
dave_thompson_085

@nakajuice: Bạn cần OpenSSL phiên bản 1.0.0 (phát hành 2010) trở lên. AIUI Apple đã ngừng hỗ trợ OpenSSL trên OS (X), vì vậy bạn có thể cần một phiên bản từ brew hoặc tương tự.
dave_thompson_085,

Điều này đã giúp tôi đi đúng hướng để chuyển đổi từ định dạng OpenSSH. Tôi đã kết thúc bằng cách sử dụng ssh-keygen như thế này: ssh-keygen -i -f ~ / .ssh / id_rsa.pub -e -m PKCS8> ~ / .ssh / id_rsa.pub.pem
Bradley Kreider

13

Mặc dù các nhận xét ở trên liên quan đến tiêu đề 32 byte, định dạng OID và những thứ như vậy rất thú vị, nhưng cá nhân tôi không thấy hành vi tương tự, giả sử rằng tôi đang hiểu chính xác. Tôi nghĩ có thể hữu ích nếu bạn khám phá thêm điều này trong điều mà hầu hết mọi người có thể nghĩ là quá chi tiết. Không có gì vượt quá giống như dư thừa.

Để bắt đầu, tôi đã tạo một khóa cá nhân RSA và kiểm tra nó:

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

(Ôi, thật kinh khủng! Tôi đã để lộ khóa cá nhân. Meh ...)

Tôi giải nén và hiển thị khóa công khai của nó:

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

Điều đó xảy ra có một tham số đầu ra khóa công khai khác (như đã đề cập trong một nhận xét trước đó). Thay vào đó, tôi trích xuất và hiển thị khóa công khai bằng từ khóa đó:

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

Chà, tốt. Hai giá trị khóa công khai này không giống nhau, mặc dù chúng được lấy từ cùng một khóa riêng. Hoặc la họ giông nhau? Tôi cắt và dán hai chuỗi khóa công khai vào tệp riêng của chúng, sau đó thực hiện kiểm tra mô-đun trên mỗi:

>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' nói với rsa rằng đây thực sự được coi là một khóa công khai, và đừng phàn nàn rằng nó không phải là một khóa riêng tư.

Bây giờ chúng ta lấy khóa công khai RSA, hiển thị mô-đun và chuyển nó thành một 'khóa công khai' cũ thuần túy (một lần nữa, chúng ta phải nói với nó rằng đầu vào là khóa công khai):

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

Cùng một mô-đun và cùng một giá trị 'khóa công khai' được hiển thị. Để làm cho mọi thứ thú vị hơn (đối với tôi, dù sao), khi chúng tôi sử dụng từ khóa RSAPublicKey_out, chúng tôi nhận được:

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

... và khi chúng tôi chuyển đổi 'khóa công khai' cũ thuần túy thành khóa công khai 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-----

... tiến hành không ngừng và mặc dù chúng tôi chỉ mới thực hiện điều này một vài lệnh trước đây, nhưng để làm rõ vấn đề, chúng tôi sẽ lật lại mọi thứ để chuyển đổi từ RSA sang 'khóa công khai' cũ:

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

... đưa chúng tôi trở lại ngay nơi chúng tôi bắt đầu. Chúng ta đã học được gì?

Tóm lại: các phím bên trong đều giống nhau, chúng chỉ khác nhau. Một nhận xét trước đó đã chỉ ra định dạng khóa RSA được xác định trong PKCS # 1 và định dạng 'khóa công khai' cũ thuần túy được xác định trong PKCS # 8. Tuy nhiên, chỉnh sửa một biểu mẫu không biến nó thành biểu mẫu kia. Hy vọng rằng bây giờ tôi đã đánh bại sự khác biệt này đến chết.

Tuy nhiên, trong trường hợp vẫn còn một chút sự sống, hãy làm nổi bật điều này một chút và tham khảo chứng chỉ ban đầu được tạo bằng khóa riêng RSA cách đây rất lâu, kiểm tra khóa công khai và mô-đun của nó:

>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

... và tất cả họ đều sống hạnh phúc mãi mãi về sau: chứng chỉ có cùng giá trị mô đun như khóa công khai RSA, khóa riêng RSA và 'khóa công khai' cũ. Chứng chỉ chứa cùng một giá trị 'khóa công khai' cũ mà chúng ta đã thấy trước đó, mặc dù nó đã được ký bằng tệp được đánh dấu là khóa riêng RSA. Thật an toàn khi nói rằng có một sự đồng thuận.

Không có từ khóa tương đương 'RSAPublicKey_out' trong góc phần tư X509 của thiên hà OpenSSL, vì vậy chúng tôi không thể thử điều đó, mặc dù giá trị mô-đun được mô tả là "mô-đun khóa RSA" mà tôi cho là gần bằng chúng tôi sẽ nhận được.

Tất cả điều này sẽ trông như thế nào với chứng chỉ có chữ ký của DSA, tôi không biết.

Tôi nhận ra rằng điều này không trả lời câu hỏi ban đầu, nhưng có lẽ nó cung cấp một số nền tảng hữu ích. Nếu không, tôi xin lỗi. Ít nhất, những điều không nên làm và những giả định không nên làm.

Không nghi ngờ gì nữa, người ta đã ghi nhận sự lặp lại hơi khó chịu của "viết khóa RSA", khi nó không thực hiện bất kỳ điều gì như vậy. Tôi cho rằng điều có nghĩa là mô-đun rsa nhận ra khóa công khai cũ thuần túy là khóa RSA thực sự và đó là lý do tại sao nó tiếp tục hoạt động trên "khóa RSA" (sau cùng thì nó cũng là mô-đun rsa). Nếu tôi nhớ lại một cách chính xác, thì cấu trúc EVP_PKEY chung có sự kết hợp cho tất cả các loại khóa, với mỗi loại khóa có bộ giá trị đặc biệt riêng (được đặt tên hữu ích là g, w, q và các phụ âm khác).

Cuối cùng, tôi lưu ý rằng có một khiếu nại liên quan đến lập trình & phát triển; bây giờ, mỗi lệnh OpenSSL rõ ràng là có mã tương ứng, và nếu người ta muốn khám phá tất cả những điều kỳ diệu trong lập trình OpenSSL ngày nay, dòng lệnh sẽ có vẻ là một nơi hợp lý để bắt đầu. Trong trường hợp cụ thể này (vì tôi đang sử dụng cygwin gần đây tại thời điểm này), người ta có thể bắt đầu bằng cách xem lại \ openssl-1.0.2f \ apps \ rsa.c và (được cho là có dung sai cao cho macro) \ openssl-1.0. 2f \ crypto \ pem \ pem_all.c


8

Sự khác biệt duy nhất giữa pub1 và pub2 của bạn, bên cạnh những header / footer, là chuỗi bổ sung này trong pub2: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A. Nếu bạn loại bỏ điều đó, Cơ sở 64 giống hệt với Cơ sở trong pub1.

Chuỗi phụ tương ứng với định danh thuật toán theo Câu trả lời này .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.