"BEGIN RSA PUBLIC KEY", 다른 하나는 "BEGIN PUBLIC KEY"라는 두 가지 스타일의 공개 키 형식간에 어떻게 변환 할 수 있습니까?


97

두 가지 스타일의 공개 키 형식을 어떻게 변환 할 수 있습니까? 한 가지 형식은 다음과 같습니다.

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

다른 형식은 다음과 같습니다.

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

예를 들어 ssh-keygen 명령을 사용하여 id_rsa / id_rsa.pub 쌍을 생성하고 다음을 사용하여 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는 프로그래밍 및 개발 질문을위한 사이트입니다. 이 질문은 프로그래밍이나 개발에 관한 것이 아니기 때문에 주제에서 벗어난 것처럼 보입니다. 도움말 센터에서 내가 질문 할 수있는 주제를 참조 하세요 . 아마 슈퍼 사용자 또는 유닉스 및 리눅스 스택 교환 물어 더 나은 장소가 될 것입니다.
jww

답변:


12

순수한 PHP RSA 구현 인 phpseclib 사용 ...

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

헤더에 BEGIN RSA PUBLIC KEY가 아니라 BEGIN PUBLIC KEY라고 표시되어 있어도 base64로 인코딩 된 항목이 일치하는 것으로 보입니다. 그래서 아마도 str_replace를 사용하여 그것을 고 치시면 좋습니다!


312

여기서 무슨 일이 일어나고 있는지 설명하고 싶었습니다.

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

그러면이 숫자를 컴퓨터에 저장하는 방법이 문제가됩니다. 먼저 두 가지를 모두 16 진수로 변환합니다.

  • 계수 : EB506399F5C612F5A67A09C1192B92FAB53DB28520D859CE0EF6B7D83D40AA1C1DCE2C0720D15A0F531595CAD81BA5D129F91CC6769719F1435872C4BCD0521150A0263B470066489B918BFCA03CE8A0E9FC2C0314C4B096EA30717C03C28CA29E678E63D78ACA1E9A63BDB1261EE7A0B041AB53746D68B57B68BEF37B71382838C95DA8557841A3CA58109F0B4F77A5E929B1A25DC2D6814C55DC0F81CD2F4E5DB95EE70C706FC02C4FCA358EA9A82D8043A47611195580F89458E3DAB5592DEFE06CDE1E516A6C61ED78C13977AE9660A9192CA75CD72967FD3AFAFA1F1A2FF6325A5064D847028F1E6B2329E8572F36E708A549DDA355FC74A32FDD8DBA65
  • 지수 : 010001

RSA는 첫 번째 형식을 발명했습니다.

RSA는 먼저 형식을 발명했습니다.

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

그들은 ASN.1 바이너리 인코딩 표준의 DER 특징을 사용하여 두 개의 숫자를 표현하기로 결정했습니다 [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뿐만 아니라

그 후 다른 형태의 공개 키 암호화가 등장했습니다.

  • Diffie-Hellman
  • 타원 곡선

이러한 암호화 알고리즘 의 매개 변수를 표현하는 방법에 대한 표준을 만들 때 사람들은 RSA가 원래 정의한 것과 동일한 아이디어를 많이 채택했습니다.

  • ASN.1 바이너리 인코딩 사용
  • base64 그것
  • 다섯 개의 하이픈으로 감싸
  • 그리고 단어 BEGIN PUBLIC KEY

그러나 다음을 사용하는 대신 :

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

대신 그들은 따라야 할 OID (Object Identifier)를 포함하기로 결정했습니다. 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 바이트는 4 개의 문자가됩니다.

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

파일의 16 진 구조를 인쇄하기 위해 어떤 도구를 사용 했습니까?
Buge

7
@Buge 저는 훌륭하고 우수한 ASN.1 JavaScript 디코더를 사용했습니다 . That과 TRANSLATOR, BINARY 는 트릭 도구 상자에 포함 할 수있는 두 가지 훌륭한 도구입니다.
Ian Boyd

1
계수의 시작에는 추가 "1"문자가 있습니다. 이렇게 시작해야합니다 ... 297,056,429,939,040,947,991,047,334,197,581,225,628,107,02,573 ...하지만 이건 아닙니다 ...
EmpathicSage


51

이 웹 사이트가 다양한 형식에 대한 좋은 기술 설명이라는 것을 알았습니다 : https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem

"BEGIN RSA PUBLIC KEY"는 RSA 키만 포함 할 수있는 PKCS # 1입니다.

"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은 그 점에서 잘못되었습니다. 일반 형식의 publickey는 Ian Boyd의 (long!) 답변에 올바르게 명시된대로 X.509 및 특히 SubjectPublicKeyInfo 형식에 의해 정의됩니다. 이 정보는 RFC3279의 '기본'RSA와 함께 알고리즘에 따라 RFC5280과 다른 RFC에 (더 편리하게) 복제됩니다.
dave_thompson_085

@nakajuice : OpenSSL 버전 1.0.0 (2010 년 출시) 이상이 필요합니다. AIUI Apple은 OS (X)에서 OpenSSL 지원을 중단 했으므로 brew 또는 이와 유사한 버전이 필요할 수 있습니다.
dave_thompson_085

이것은 OpenSSH 형식에서 변환하기위한 올바른 방향으로 나아갔습니다. SSH-Keygen은 -i -f ~ / 스푸핑 / id_rsa.pub -e -m PKCS8> ~ / 스푸핑 / id_rsa.pub.pem :이 같은 SSH-Keygen은을 사용하여 종료
브래들리 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-----

(오, 공포! 개인 키를 노출했습니다. 음 ...)

공개 키를 추출하여 표시합니다.

>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를 알려줍니다 되는 공개 키를 있어야하는데, 그것은 개인 키 아니라고 불평하지 않습니다.

이제 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 개인 키로 표시된 파일로 서명되었지만 이전에 본 것과 동일한 일반 이전 '공개 키'값이 포함되어 있습니다. 합의가 있다고 말하는 것이 안전합니다.

OpenSSL 은하의 X509 사분면에는 '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의 것과 동일합니다.

추가 문자열은 이 Answer 에 따른 알고리즘 식별자에 해당합니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.