证书修复
题目:
#break.pem
-----BEGIN BREAK PEM PRIVATE-----
MIIEowIBAAKCAQEAw6JUixKmoIZjLyR1Qc/D/3mfTC3YvqKienLM7Nt/83UqpYeg
9rOw02xLtIqgBdVyVkI+MknQdB5tB1W/bo95M8JjmNxi5rcEzXK4A5HiKtNxK9hC
dE1GIt78XcT1FLoM86zxFonkDQ8LxHXPbU22+Ex8ov269pS/BEwZuKohqbIUU4iZ
UltNYW2kaVsavAZw4NyQcQCQoijprdrQZLV6XjC/3+uX6baLaZS+NWHm1M16UHde
IF9B1gNuifO0xnuAWxRENjBIXw/3W8OVvRuRUppY2WYgeEG31fgfOCDoXhWVbqAD
6fJA9JWdkOPDqUAsqFCr2VKnORa2X9V9HdO5lwIDAQABAoIBAQD/////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////AoGBAP//////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////AoGBAP//
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////AoGAZFBey/5KFQ1nOL6xe00r
ehGXxxNQF/7oym0kzI6BBi4awYZ4FCtuGiiAfkcsOS0UhlhFn1gEemnl2f2EF78M
THN5zVM5FSY5Cf8XwJT/fEytuWdCQke7JxVYOLNsEJeViicsasXeWeSL1nPYS3a5
+T4027LUdjikIbu508dTT6UCgYAY+t0pv5nJ93J3773ZZYkLSCG+zXZBSgUtcCoQ
GTBa4Qcr3MLeeUGDkb4qNIBdqWsQR0GiIXLkoIxcmOr66Rs+Hl60MD0kWQA6uz5/
aJOhZc8pO0vGVG3+RbKA4xTxZshopp4CVdCrM20SqXXa3OEqr48Ec1aIES/ymZO8
GuaOwQKBgB4ZWvOfPzCFOselDYyjz2Tub1RY3YrvI1do3jl42nhy/1Aoc6G3XLi4
AIg8gxJGx36aPjpxBfe1HTicBhtUThBxq/A2/Ed1TwxFDvDPjhDc1Js/LL0qxhaP
Z/xYCgGGZftjQqPTy+S62ppYVcTxjDON6vNBssatGUIzuGglC2Lf
-----END BREAK PEM PRIVATE-----
2280855825153079369164514405327170396436620371664464526496429415733055203155893358484242996086505609777681080427906338470140692619928813296029361848636902023401977358243759630394370381376771421271028169492126347929997983519619222735581769019133156193638407197605823449074124544232663174637158818370904094998560600412703805652546502801423946150024740398302185572802694514470006408627417645654400501165391976205173956917696904810606259304153658230235808250378495226246727449749944446621780268923502478344984402162063011322533642498211989023200258638304752854056875616723925602248635708248865548095231743243612632966212
解题思路:
- 首先题目给出了
c
以及破损私钥文件 - 在PKCS#1 RSA算法标准中定义RSA公钥结构如下
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
- 在PKCS#1 RSA算法标准中定义RSA私钥结构如下
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1) (dp)
exponent2 INTEGER, -- d mod (q-1) (dq)
coefficient INTEGER, -- (inverse of q) mod p (inv)
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
- 能提取出
n,e,dp,dq,inv
- 假设我们有公钥就这么提取(将base64字符串解码后,再转换为16进制)
import base64
common_key = '''MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzGjK21FO8/FjPZM+gGJ3
TvykTBocH9CReiBWuzkZwZmVt6wTJzerWS+DPRFJo7IviUxR0VOncEwxNgBzy5Ii
DXDvR6gwSXRjCvKD8fHBg3I96Lj2yV29t0J0mVyCoWqVAnxv09cUBIa25K5vmUIU
Pd1pA1m2xDLCQ54knHUjwK/fayGMrHHrT+bhSSFSIIguqKUOQ5ucgwWApTTF8CF7
yXITpq3kkYoZtSS4XewWr90xE+4v6vXNJ6vWJnxjaztEJ5meThH0DTgGTyq2/R59
jlCQ7suLqjH0S8HtSGQ4bM7sJkL+3WWDoyCgqKNvMpJmx9cQ5Gq8qgQ5ZZnqEI+0
MQIDAjKf'''
#common_key = "".join(common_key.split("\n"))
common_key = common_key.split("\n")
for i in common_key:
print(base64.b64decode(i).hex())
'''
30820122300d06092a864886f70d01010105000382010f003082010a0282010100cc68cadb514ef3f1633d933e806277
4efca44c1a1c1fd0917a2056bb3919c19995b7ac132737ab592f833d1149a3b22f894c51d153a7704c31360073cb9222
0d70ef47a8304974630af283f1f1c183723de8b8f6c95dbdb74274995c82a16a95027c6fd3d7140486b6e4ae6f994214
3ddd690359b6c432c2439e249c7523c0afdf6b218cac71eb4fe6e149215220882ea8a50e439b9c830580a534c5f0217b
c97213a6ade4918a19b524b85dec16afdd3113ee2feaf5cd27abd6267c636b3b4427999e4e11f40d38064f2ab6fd1e7d
8e5090eecb8baa31f44bc1ed4864386cceec2642fedd6583a320a0a8a36f329266c7d710e46abcaa04396599ea108fb4
31020302329f
'''
30820122:表示后面是一个SEQUENCE,总长度为0x122
,即使290
字节
02820101:表示后面是一个INTEGER,长度是0101
即257
字节,后面跟的00…
即为**n**
的内容,257
字节
0203:表示后面是一个INTEGER,长度是03
即3
字节,内容0x02329f
,这就是**e**
- 这里我们有私钥,就这么提取(将base64字符串解码后,再转换为16进制)
import base64
private_key = '''MIIEowIBAAKCAQEAw6JUixKmoIZjLyR1Qc/D/3mfTC3YvqKienLM7Nt/83UqpYeg
9rOw02xLtIqgBdVyVkI+MknQdB5tB1W/bo95M8JjmNxi5rcEzXK4A5HiKtNxK9hC
dE1GIt78XcT1FLoM86zxFonkDQ8LxHXPbU22+Ex8ov269pS/BEwZuKohqbIUU4iZ
UltNYW2kaVsavAZw4NyQcQCQoijprdrQZLV6XjC/3+uX6baLaZS+NWHm1M16UHde
IF9B1gNuifO0xnuAWxRENjBIXw/3W8OVvRuRUppY2WYgeEG31fgfOCDoXhWVbqAD
6fJA9JWdkOPDqUAsqFCr2VKnORa2X9V9HdO5lwIDAQABAoIBAQD/////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////AoGBAP//////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////AoGBAP//
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////AoGAZFBey/5KFQ1nOL6xe00r
ehGXxxNQF/7oym0kzI6BBi4awYZ4FCtuGiiAfkcsOS0UhlhFn1gEemnl2f2EF78M
THN5zVM5FSY5Cf8XwJT/fEytuWdCQke7JxVYOLNsEJeViicsasXeWeSL1nPYS3a5
+T4027LUdjikIbu508dTT6UCgYAY+t0pv5nJ93J3773ZZYkLSCG+zXZBSgUtcCoQ
GTBa4Qcr3MLeeUGDkb4qNIBdqWsQR0GiIXLkoIxcmOr66Rs+Hl60MD0kWQA6uz5/
aJOhZc8pO0vGVG3+RbKA4xTxZshopp4CVdCrM20SqXXa3OEqr48Ec1aIES/ymZO8
GuaOwQKBgB4ZWvOfPzCFOselDYyjz2Tub1RY3YrvI1do3jl42nhy/1Aoc6G3XLi4
AIg8gxJGx36aPjpxBfe1HTicBhtUThBxq/A2/Ed1TwxFDvDPjhDc1Js/LL0qxhaP
Z/xYCgGGZftjQqPTy+S62ppYVcTxjDON6vNBssatGUIzuGglC2Lf
'''
private_key = private_key.split("\n")
for i in private_key:
print(base64.b64decode(i).hex())
'''
308204a30201000282010100c3a2548b12a6a086632f247541cfc3ff799f4c2dd8bea2a27a72ccecdb7ff3752aa587a0
f6b3b0d36c4bb48aa005d57256423e3249d0741e6d0755bf6e8f7933c26398dc62e6b704cd72b80391e22ad3712bd842
744d4622defc5dc4f514ba0cf3acf11689e40d0f0bc475cf6d4db6f84c7ca2fdbaf694bf044c19b8aa21a9b214538899
525b4d616da4695b1abc0670e0dc90710090a228e9addad064b57a5e30bfdfeb97e9b68b6994be3561e6d4cd7a50775e
205f41d6036e89f3b4c67b805b14443630485f0ff75bc395bd1b91529a58d966207841b7d5f81f3820e85e15956ea003
e9f240f4959d90e3c3a9402ca850abd952a73916b65fd57d1dd3b99702030100010282010100ffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffff02818100ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02818100ffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02818064505ecbfe4a150d6738beb17b4d2b
7a1197c7135017fee8ca6d24cc8e81062e1ac18678142b6e1a28807e472c392d148658459f58047a69e5d9fd8417bf0c
4c7379cd533915263909ff17c094ff7c4cadb967424247bb27155838b36c1097958a272c6ac5de59e48bd673d84b76b9
f93e34dbb2d47638a421bbb9d3c7534fa502818018fadd29bf99c9f77277efbdd965890b4821becd76414a052d702a10
19305ae1072bdcc2de79418391be2a34805da96b104741a22172e4a08c5c98eafae91b3e1e5eb4303d2459003abb3e7f
6893a165cf293b4bc6546dfe45b280e314f166c868a69e0255d0ab336d12a975dadce12aaf8f04735688112ff29993bc
1ae68ec10281801e195af39f3f30853ac7a50d8ca3cf64ee6f5458dd8aef235768de3978da7872ff502873a1b75cb8b8
00883c831246c77e9a3e3a7105f7b51d389c061b544e1071abf036fc47754f0c450ef0cf8e10dcd49b3f2cbd2ac6168f
67fc580a018665fb6342a3d3cbe4bada9a5855c4f18c338deaf341b2c6ad194233b868250b62df
'''
308204a3:表示后面是一个SEQUENCE,总长度为0x4a3
,即使1187
字节
第一个02820101:表示后面是一个INTEGER,长度是0101
即257
字节,后面的00…
即为**n**
的内容,257
字节
0203:表示后面是一个INTEGER,长度是03
即3
字节,内容0x10001
,这就是**e**
第二个02820101:表示后面是一个INTEGER,长度是0101
即257
字节,后面的00…
即为**d**
的内容,257
字节
第一个028181:表示INTEGER,长度为129
字节,其内容为**p**
第二个028181:表示INTEGER,长度为129
字节,其内容为**q**
第一个028180:表示INTEGER,长度为128
字节,其内容为**dp**
第二个028180:表示INTEGER,长度为128
字节,其内容为**dq**
第三个028180:表示INTEGER,长度为128
字节,其内容为**inv**
- 最后根据
**dp**
泄露攻击解题即可
解答:
from Crypto.Util.number import *
import gmpy2
c = 2280855825153079369164514405327170396436620371664464526496429415733055203155893358484242996086505609777681080427906338470140692619928813296029361848636902023401977358243759630394370381376771421271028169492126347929997983519619222735581769019133156193638407197605823449074124544232663174637158818370904094998560600412703805652546502801423946150024740398302185572802694514470006408627417645654400501165391976205173956917696904810606259304153658230235808250378495226246727449749944446621780268923502478344984402162063011322533642498211989023200258638304752854056875616723925602248635708248865548095231743243612632966212
n = int("c3 a2 54 8b 12 a6 a0 86 63 2f 24 75 41 cf c3 ff 79 9f 4c 2d d8 be a2 a2 7a 72 cc ec db 7f f3 75 2a a5 87 a0 f6 b3 b0 d3 6c 4b b4 8a a0 05 d5 72 56 42 3e 32 49 d0 74 1e 6d 07 55 bf 6e 8f 79 33 c2 63 98 dc 62 e6 b7 04 cd 72 b8 03 91 e2 2a d3 71 2b d8 42 74 4d 46 22 de fc 5d c4 f5 14 ba 0c f3 ac f1 16 89 e4 0d 0f 0b c4 75 cf 6d 4d b6 f8 4c 7c a2 fd ba f6 94 bf 04 4c 19 b8 aa 21 a9 b2 14 53 88 99 52 5b 4d 61 6d a4 69 5b 1a bc 06 70 e0 dc 90 71 00 90 a2 28 e9 ad da d0 64 b5 7a 5e 30 bf df eb 97 e9 b6 8b 69 94 be 35 61 e6 d4 cd 7a 50 77 5e 20 5f 41 d6 03 6e 89 f3 b4 c6 7b 80 5b 14 44 36 30 48 5f 0f f7 5b c3 95 bd 1b 91 52 9a 58 d9 66 20 78 41 b7 d5 f8 1f 38 20 e8 5e 15 95 6e a0 03 e9 f2 40 f4 95 9d 90 e3 c3 a9 40 2c a8 50 ab d9 52 a7 39 16 b6 5f d5 7d 1d d3 b9 97".replace(" ", ""), 16)
e = 65537
dp = int("64 50 5e cb fe 4a 15 0d 67 38 be b1 7b 4d 2b 7a 11 97 c7 13 50 17 fe e8 ca 6d 24 cc 8e 81 06 2e 1a c1 86 78 14 2b 6e 1a 28 80 7e 47 2c 39 2d 14 86 58 45 9f 58 04 7a 69 e5 d9 fd 84 17 bf 0c 4c 73 79 cd 53 39 15 26 39 09 ff 17 c0 94 ff 7c 4c ad b9 67 42 42 47 bb 27 15 58 38 b3 6c 10 97 95 8a 27 2c 6a c5 de 59 e4 8b d6 73 d8 4b 76 b9 f9 3e 34 db b2 d4 76 38 a4 21 bb b9 d3 c7 53 4f a5".replace(" ", ""), 16)
dq = int("18 fa dd 29 bf 99 c9 f7 72 77 ef bd d9 65 89 0b 48 21 be cd 76 41 4a 05 2d 70 2a 10 19 30 5a e1 07 2b dc c2 de 79 41 83 91 be 2a 34 80 5d a9 6b 10 47 41 a2 21 72 e4 a0 8c 5c 98 ea fa e9 1b 3e 1e 5e b4 30 3d 24 59 00 3a bb 3e 7f 68 93 a1 65 cf 29 3b 4b c6 54 6d fe 45 b2 80 e3 14 f1 66 c8 68 a6 9e 02 55 d0 ab 33 6d 12 a9 75 da dc e1 2a af 8f 04 73 56 88 11 2f f2 99 93 bc 1a e6 8e c1".replace(" ", ""), 16)
inv = int("1e 19 5a f3 9f 3f 30 85 3a c7 a5 0d 8c a3 cf 64 ee 6f 54 58 dd 8a ef 23 57 68 de 39 78 da 78 72 ff 50 28 73 a1 b7 5c b8 b8 00 88 3c 83 12 46 c7 7e 9a 3e 3a 71 05 f7 b5 1d 38 9c 06 1b 54 4e 10 71 ab f0 36 fc 47 75 4f 0c 45 0e f0 cf 8e 10 dc d4 9b 3f 2c bd 2a c6 16 8f 67 fc 58 0a 01 86 65 fb 63 42 a3 d3 cb e4 ba da 9a 58 55 c4 f1 8c 33 8d ea f3 41 b2 c6 ad 19 42 33 b8 68 25 0b 62 df".replace(" ", ""), 16)
def dp_leak(dp, c, n, e):
for i in range(1, e):
t = (dp * e - 1) % i
if t == 0:
p = (dp * e - 1) // i + 1
if n % p == 0:
q = n // p
d = gmpy2.invert(e, (p - 1) * (q - 1))
print(long_to_bytes(pow(c, d, n)))
dp_leak(dp, c, n, e)
#NSSCTF{(115.36517E, 39.30839N)}