ฉันอยากจะช่วยอธิบายว่าเกิดอะไรขึ้นที่นี่
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
รูปแบบเก่า