nssRound16
[TOC]
Crypto
pr
题面:
crt
考点:同余性质 CRT
题目:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 from Crypto.Util.number import *import randomflag=plaintext = 'NSSCTF{****************}' charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' padding_length = 100 - len (plaintext) for _ in range (padding_length): plaintext += random.choice(charset) print (plaintext)public_exponent = 31413537523 message = bytes_to_long(plaintext.encode()) assert message > (1 << 512 )assert message < (1 << 1024 )prime_p = getPrime(512 ) prime_q = getPrime(512 ) prime_r = getPrime(512 ) n1 = prime_p * prime_q n2 = prime_q * prime_r ciphertext1 = pow (message, public_exponent, n1) ciphertext2 = pow (message, public_exponent, n2) print ('c1=' , ciphertext1)print ('c2=' , ciphertext2)print ('p=' , prime_p)print ('r=' , prime_r)c1= 36918910341116680090654563538246204134840776220077189276689868322808977412566781872132517635399441578464309667998925236488280867210758507758915311644529399878185776345227817559234605958783077866016808605942558810445187434690812992072238407431218047312484354859724174751718700409405142819140636116559320641695 c2= 15601788304485903964195122196382181273808496834343051747331984997977255326224514191280515875796224074672957848566506948553165091090701291545031857563686815297483181025074113978465751897596411324331847008870832527695258040104858667684793196948970048750296571273364559767074262996595282324974180754813257013752 p= 12101696894052331138951718202838643670037274599483776996203693662637821825873973767235442427190607145999472731101517998719984942030184683388441121181962123 r= 10199001137987151966640837133782537428248507382360655526592866939552984259171772190788036403425837649697437126360866173688083643144865107648483668545682383
解题:
题目流程简化分析:
1 2 3 4 5 6 7 8 e = 31413537523 n1 = p * q n2 = q * r c1 = pow (m, e, n1) c2 = pow (m, e, n2) => c1 = pow (m, e, p * q) c2 = pow (m, e, q * r)
已知:p、r、c1、c2
利用同余的性质推导:
先根据放到缩小模数原理 对c1进行操作
c 1 = m e m o d p 两边同乘 q c 1 ∗ q = m e ∗ q m o d ( p ∗ q ) c_1~=~m^e~mod~p\\
两边同乘q\\
c_1*q = m^e*q~mod~(p*q)
c 1 = m e m o d p 两 边 同 乘 q c 1 ∗ q = m e ∗ q m o d ( p ∗ q )
后面利用除法原理
其中k代表q m代表p*qk与p*q 互质=>
c 1 = m e m o d ( p ∗ q ) c1=m^e~mod~(p*q)
c 1 = m e m o d ( p ∗ q )
简单来说就是 在同余关系中 模数的因子作为模数仍然存在同余关系,即:
c 1 = m e m o d p ∗ q = > c 1 = m e m o d p c_1~=~m^e~mod~p*q\\
=>~~c_1~=~m^e~mod~p
c 1 = m e m o d p ∗ q = > c 1 = m e m o d p
c2同理
c 2 = m e m o d q ∗ r = > c 2 = m e m o d r c_2~=~m^e~mod~q*r\\
=>~~c_2~=~m^e~mod~r
c 2 = m e m o d q ∗ r = > c 2 = m e m o d r
利用中国剩余定理crt,对c1=>p c2=>r
得到的结果是在p*r域内的$$m^e$$ 也就是对应的密文c
p r已知 在该域下进行基础的RSA解密
完整exp:
1 2 3 4 5 6 7 8 9 10 11 12 c1= ... c2= ... p= ... r= ... import gmpy2e = 31413537523 final_c= crt(c1,c2,p,r) d = gmpy2.invert(e,(p-1 )*(r-1 )) from Crypto.Util.number import *print (long_to_bytes(int (pow (final_c,d,p*r))))
break
考点:私钥文件 破损修复
题目:
破损私钥文件:
1 2 Bc8tSTrvGJm2oYuCzIz+Yg4nwwKBgQDiYUawe5Y+rPbFhVOMVB8ZByfMa4LjeSDdZ23jEGvylBHSeyvFCQq3ISUE40k1D2XmmeaZML3a1nUn6ORIWGaG2phcwrWLkR6nubVmb1QJSzgzmFHGnL56KHByZxD9q6DPB+o6gGWt8/6ddBl2NIZU/1btdPQgojfAXXJFzR92RQKBgQC7qlB0U7m2U4FdG9eelSd+WSKNUVllZAuHji7jgh7Ox6La9xN5miGZ1yvP44yX218OJ9Zi08o6vIrM6Eil45KzTtGm4iuIn8CMpox+5eUtoxyvxa9rs2Wu+IRZN9zCME+p+qI8/TG27dIyDzsdgNqcUo8ESls7uW5/FEA7bYTCiQKBgQC71KybeB+kZ0zlfIdi8tVOpeI+uaHDbdh3+/5wHUsD3hmfg7VAag0q/2RA1vkB/oG1QVLVHl0Yu0I/1/u5jyeakrtClAegAsvlrK+3i321rGS4YpTPb3SX1P/f3GZ7o7DstouA+NHk8IL9T7xkmJYw5h/RLG32ucH6aU6MXfLR5QKBgD/skfdFxGWxhHk6U1mS27IM9jJNg9xLz5nxzkqPPhLn+rdgIIuTuQtv++eEjEP++7ZV10rg5yKVJd/bxy8H2IN7aQo7kZWulHTQDZMFwgOhn0u6glJi+qC8bWzYDFOQSFrY9XQ3vwKMspqm+697xM+dMUW0LML6oUE9ZjEiAY/5 -----END PRIVATE KEY-----
密文c:
1 6081370370545409218106271903400346695565292992689150366474451604281551878507114813906275593034729563149286993189430514737137534129570304832172520820901940874698337733991868650159489601159238582002010625666203730677577976307606665760650563172302688129824842780090723167480409842707790983962415315804311334507726664838464859751689906850572044873633896253285381878416855505301919877714965930289139921111644393144686543207867970807469735534838601255712764863973853116693691206791007433101433703535127367245739289103650669095061417223994665200039533840922696282929063608853551346533188464573323230476645532002621795338655
解题:
首先对私钥文件恢复
第一步base64解密 得到的是乱码 转为16进制
1 2 3 4 5 6 7 8 9 10 11 12 13 05cf2d493aef1899b6a18b82cc8cfe620e27c3 #02整型 长度0x81 推测p 02818100e26146b07b963eacf6c585538c541f190727cc6b82e37920dd676de3106bf29411d27b2bc5090ab7212504e349350f65e699e69930bddad67527e8e448586686da985cc2b58b911ea7b9b5666f54094b38339851c69cbe7a2870726710fdaba0cf07ea3a8065adf3fe9d741976348654ff56ed74f420a237c05d7245cd1f7645 #02整型 长度0x81 推测q 02818100bbaa507453b9b653815d1bd79e95277e59228d515965640b878e2ee3821ecec7a2daf713799a2199d72bcfe38c97db5f0e27d662d3ca3abc8acce848a5e392b34ed1a6e22b889fc08ca68c7ee5e52da31cafc5af6bb365aef8845937dcc2304fa9faa23cfd31b6edd2320f3b1d80da9c528f044a5b3bb96e7f14403b6d84c289 #02整型 长度0x81 推测dp 02818100bbd4ac9b781fa4674ce57c8762f2d54ea5e23eb9a1c36dd877fbfe701d4b03de199f83b5406a0d2aff6440d6f901fe81b54152d51e5d18bb423fd7fbb98f279a92bb429407a002cbe5acafb78b7db5ac64b86294cf6f7497d4ffdfdc667ba3b0ecb68b80f8d1e4f082fd4fbc64989630e61fd12c6df6b9c1fa694e8c5df2d1e5 #02整型 长度128字节 推测dq 0281803fec91f745c465b184793a535992dbb20cf6324d83dc4bcf99f1ce4a8f3e12e7fab760208b93b90b6ffbe7848c43fefbb655d74ae0e7229525dfdbc72f07d8837b690a3b9195ae9474d00d9305c203a19f4bba825262faa0bc6d6cd80c5390485ad8f57437bf028cb29aa6fbaf7bc4cf9d3145b42cc2faa1413d663122018ff9
上面的结果按照02进行切分 注意不是切所有02!
关于RSA私钥格式前置知识:参考laz佬博客-rsa
其中整数数据格式举例028180
02
: 整数的tag
81
: 长度类型 后面跟长度 比如128byte
80
: 整数占128byte
后面跟的则是value
关于私钥格式的顺序:
因为我们的破损文件只有后半部分,按照类型形成下面的预测
注意取值的时候 去掉tag信息 只保留028181
这类信息后面的值
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from Crypto.Util.number import *c = 6081370370545409218106271903400346695565292992689150366474451604281551878507114813906275593034729563149286993189430514737137534129570304832172520820901940874698337733991868650159489601159238582002010625666203730677577976307606665760650563172302688129824842780090723167480409842707790983962415315804311334507726664838464859751689906850572044873633896253285381878416855505301919877714965930289139921111644393144686543207867970807469735534838601255712764863973853116693691206791007433101433703535127367245739289103650669095061417223994665200039533840922696282929063608853551346533188464573323230476645532002621795338655 p = 0x00e26146b07b963eacf6c585538c541f190727cc6b82e37920dd676de3106bf29411d27b2bc5090ab7212504e349350f65e699e69930bddad67527e8e448586686da985cc2b58b911ea7b9b5666f54094b38339851c69cbe7a2870726710fdaba0cf07ea3a8065adf3fe9d741976348654ff56ed74f420a237c05d7245cd1f7645 q = 0x00bbaa507453b9b653815d1bd79e95277e59228d515965640b878e2ee3821ecec7a2daf713799a2199d72bcfe38c97db5f0e27d662d3ca3abc8acce848a5e392b34ed1a6e22b889fc08ca68c7ee5e52da31cafc5af6bb365aef8845937dcc2304fa9faa23cfd31b6edd2320f3b1d80da9c528f044a5b3bb96e7f14403b6d84c289 dp = 0x00bbd4ac9b781fa4674ce57c8762f2d54ea5e23eb9a1c36dd877fbfe701d4b03de199f83b5406a0d2aff6440d6f901fe81b54152d51e5d18bb423fd7fbb98f279a92bb429407a002cbe5acafb78b7db5ac64b86294cf6f7497d4ffdfdc667ba3b0ecb68b80f8d1e4f082fd4fbc64989630e61fd12c6df6b9c1fa694e8c5df2d1e5 dq = 0x3fec91f745c465b184793a535992dbb20cf6324d83dc4bcf99f1ce4a8f3e12e7fab760208b93b90b6ffbe7848c43fefbb655d74ae0e7229525dfdbc72f07d8837b690a3b9195ae9474d00d9305c203a19f4bba825262faa0bc6d6cd80c5390485ad8f57437bf028cb29aa6fbaf7bc4cf9d3145b42cc2faa1413d663122018ff9 m = pow (c, dp, p) print (long_to_bytes(m))