withopen("3.txt", "wb") as x: # 保存解密后的文件(原文) withopen("encrypt1.txt", "rb") as y:#读取密文 cipher_text = y.read()#读取密文字符串到cipher_text变量 text = rsa.decrypt(cipher_text, privkey) # 使用私钥解密 x.write(text)
生成密文
可以看到生成了密文如下
解出的原文与原文一致
深入分析加密解密过程
前面RSA加密解密小试已经完成,接下来要开始了解RSA的原理了
分析式子
我们直接看式子吧
1 2
C ≡ M^e * (mod N) //加密 M ≡ C^d * (mod N) //解密
先确定一下表层意思:
M为原文,C为加密后得到的密文
N和e为公钥,d、N为私钥
那么它们代表什么呢?
N实际上是一个大整数,d、e则是互为无反数的两个指数
加密式子
1
C ≡ M^e * (mod N)
解释:密文 = 明文的e次幂乘以N的模
解密式子
1
M ≡ C^d * (mod N)
解释:明文 = 密文的d次幂乘以N的模
这样是不是好理解一些呢?
分析原理
接下来我们来分析加密原理,这一步是为了理解它
待更新
比较简单的例题
CTFshow crypto4
题目给出了p、q和e
我们只需要按照公式来就好,这道题只需要下面三个公式
1 2 3
(Φ(n) * k + 1 ) / e = d Φ(n)= (p-1)*(q-1) n=p*q
k是整数,只需要使用整数进行遍历求解就可以了
下面是python3的解题程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#Edit by lx #公式参考:https://blog.csdn.net/qq_38313548/article/details/85387466 #Φ(n) * k + 1 =ed和(Φ(n) * k + 1 )/ e = d p=447685307 q=2037 e=17 n=p*q nn=(p-1)*(q-1)
k=1 whileTrue: d = ((nn * k) + 1) / e dd = int(d) if dd == d: break else: k += 1
print("CTF.show crypto4: flag{d} is ", "flag{0}{1}{2}".format("{", int(d), "}"))
f = open('./public.key', 'rb').read() pub = RSA.importKey(f) n = pub.n e = pub.e print(n, '\n', e) # n = 79832181757332818552764610761349592984614744432279135328398999801627880283610900361281249973175805069916210179560506497075132524902086881120372213626641879468491936860976686933630869673826972619938321951599146744807653301076026577949579618331502776303983485566046485431039541708467141408260220098592761245010678592347501894176269580510459729633673468068467144199744563731826362102608811033400887813754780282628099443490170016087838606998017490456601315802448567772411623826281747245660954245413781519794295336197555688543537992197142258053220453757666537840276416475602759374950715283890232230741542737319569819793988431443 # e = 65537
然后看看n能不能分解,
因为条件有限,想要做出的话一般都是能分解的,
可以借助各种分解n的工具或者在线网站
这题是可以分解的,分解出来p、q如下
1 2
p = 3133337 q = 25478326064937419292200172136399497719081842914528228316455906211693118321971399936004729134841162974144246271486439695786036588117424611881955950996219646807378822278285638261582099108339438949573034101215141156156408742843820048066830863814362379885720395082318462850002901605689761876319151147352730090957556940842144299887394678743607766937828094478336401159449035878306853716216548374273462386508307367713112073004011383418967894930554067582453248981022011922883374442736848045920676341361871231787163441467533076890081721882179369168787287724769642665399992556052144845878600126283968890273067575342061776244939
接下来一切都容易了,求出d然后生成私钥以解密文件,
尝试直接使用RSA算式算不能直接算出来,必须拿私钥解
1 2 3 4 5 6 7 8 9 10 11 12 13 14
from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP from Crypto.Util.number import *
p = 3133337 q = 25478326064937419292200172136399497719081842914528228316455906211693118321971399936004729134841162974144246271486439695786036588117424611881955950996219646807378822278285638261582099108339438949573034101215141156156408742843820048066830863814362379885720395082318462850002901605689761876319151147352730090957556940842144299887394678743607766937828094478336401159449035878306853716216548374273462386508307367713112073004011383418967894930554067582453248981022011922883374442736848045920676341361871231787163441467533076890081721882179369168787287724769642665399992556052144845878600126283968890273067575342061776244939 phi=(p-1)*(q-1) d=gmpy2.invert(e,phi)
from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP from Crypto.Util.number import * import base64 import gmpy2 import rsa f = open('.\public.key', 'rb').read() pub = RSA.importKey(f) n = pub.n e = pub.e print(n, '\n', e)
# n = 79832181757332818552764610761349592984614744432279135328398999801627880283610900361281249973175805069916210179560506497075132524902086881120372213626641879468491936860976686933630869673826972619938321951599146744807653301076026577949579618331502776303983485566046485431039541708467141408260220098592761245010678592347501894176269580510459729633673468068467144199744563731826362102608811033400887813754780282628099443490170016087838606998017490456601315802448567772411623826281747245660954245413781519794295336197555688543537992197142258053220453757666537840276416475602759374950715283890232230741542737319569819793988431443 # e = 65537
p = 3133337 q = 25478326064937419292200172136399497719081842914528228316455906211693118321971399936004729134841162974144246271486439695786036588117424611881955950996219646807378822278285638261582099108339438949573034101215141156156408742843820048066830863814362379885720395082318462850002901605689761876319151147352730090957556940842144299887394678743607766937828094478336401159449035878306853716216548374273462386508307367713112073004011383418967894930554067582453248981022011922883374442736848045920676341361871231787163441467533076890081721882179369168787287724769642665399992556052144845878600126283968890273067575342061776244939 phi=(p-1)*(q-1) d=gmpy2.invert(e,phi)
#key_info = RSA.construct((n, e, d, p, q)) #key = RSA.importKey(key_info.exportKey()) #key = PKCS1_OAEP.new(key) #key = rsa.PrivateKey(n,e,d,q,p) f = open('.\flag.enc', 'r').read()
p=134460556242811604004061671529264401215233974442536870999694816691450423689575549530215841622090861571494882591368883283016107051686642467260643894947947473532769025695530343815260424314855023688439603651834585971233941772580950216838838690315383700689885536546289584980534945897919914730948196240662991266027 q=161469718942256895682124261315253003309512855995894840701317251772156087404025170146631429756064534716206164807382734456438092732743677793224010769460318383691408352089793973150914149255603969984103815563896440419666191368964699279209687091969164697704779792586727943470780308857107052647197945528236341228473 phi=(p-1)*(q-1) e = [103231,97117,69557,108533,106979] d=[] for i in e: d.append(gmpy2.invert(i,phi)) print(d)
再依次解密即可
1 2 3 4 5 6 7 8 9 10 11 12
from Crypto.Util.number import getPrime, long_to_bytes, bytes_to_long, inverse import gmpy2
m=c d = [gmpy2.mpz(14976934932676584321683381078589206129802696756347452400490526455696084573015258129692134121798160701052182095773579625055482988152534986446433913203836896533116280256175147942609851284152010144289592625959098055077182547510273874680366469520622967613934401816095053670139111862241214210679418688843207294719210638623059808156603513328070063949694399651593684751165494538800859543190296638019941609102416138469099277831161767829712633873825215808675809899233312091622558923332734521949634469025857591717937024761525022508322488701416182627700447279235588065578502556218141914246088262668554149203042454115911908310703), gmpy2.mpz(5456163066690715087320481993447953020336098077226032646195134412678367908517553348084665801066919445803662455439884803615849841397425529510630693361018110614451312888862006100411867838751667824763724068918315434794777195905815326114637697844562227361928073265792791706114698362419938680722573266355483239860495738115984738276434551710706011594962374898002014841960346301695815553438493222542191889345149269329179557961899079070252028307877859707553245360807224594850647972239997678597545123073105250014889873415867041148644893646931372529032752016030171065755070279488542886213197677662096550188941698416151969760149), gmpy2.mpz(15024086703144100608380300358259382719406977034681648081709158397660796568388968274444301806306053572976616273207620544383192890753083687360230375098004028174572915807907583511198729702530708550238604058119599634446768784996796764406486651554057902600480052493140087866828751517513269631020096592636884399213526171592136163100622270081650859270616743443139937663157666369223280576135733495764121507761953952082664122323986852385046296980748569014549167425185196014846509188210816943153326070977328568075781794943605293980775097141919067574420550307640683196765763433945973704011906495769535888208516068354804409843661), gmpy2.mpz(12762167551366118071720753744231860996946029784706127808630453143965397526458562017144637131573025032347652825700705574407926404974960017901138675107791898181088334411754746792961729531047620446657788706529017031690852859630362989981642393145799974168660009557192705782072568903218272152721384118659895273792607456441482752175000904895599966587373947009470910210482039251273529151591382824028317250374946135838665754782067757582230136689327761412090471825427644488982414008809801936600403775685071388080476656096562493113134124931942591798528521358435132906022897366507245220769035091349539691776009546693221700181645), gmpy2.mpz(17312789047115721718151694136426552941284855738779804364018779659349232886160261403877195921800160981820551978627208288844536701814738862188766791962568000737911220780227869935631696179261131793895509577735783857923826531822580715078877738786352320675373439667502945538153803639887509535733732048518331639166555561603435452580318499918711921292809871549619588262475139443271531521507856705793350365006396297148290332190622868448791245935939328202068843118455938152934836416501933205585863944190269994029439678543734710002351332414419120168882166315801322919286837384476389282429234027483332019975830017618850680549227)]
for i in d: m=gmpy2.powmod(m,i,n) print(long_to_bytes(m))
完整程序如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
import gmpy2 from Crypto.Util.number import getPrime, long_to_bytes, bytes_to_long, inverse
n=21711308225346315542706844618441565741046498277716979943478360598053144971379956916575370343448988601905854572029635846626259487297950305231661109855854947494209135205589258643517961521594924368498672064293208230802441077390193682958095111922082677813175804775628884377724377647428385841831277059274172982280545237765559969228707506857561215268491024097063920337721783673060530181637161577401589126558556182546896783307370517275046522704047385786111489447064794210010802761708615907245523492585896286374996088089317826162798278528296206977900274431829829206103227171839270887476436899494428371323874689055690729986771 c=20304610279578186738172766224224793119885071262464464448863461184092225736054747976985179673905441502689126216282897704508745403799054734121583968853999791604281615154100736259131453424385364324630229671185343778172807262640709301838274824603101692485662726226902121105591137437331463201881264245562214012160875177167442010952439360623396658974413900469093836794752270399520074596329058725874834082188697377597949405779039139194196065364426213208345461407030771089787529200057105746584493554722790592530472869581310117300343461207750821737840042745530876391793484035024644475535353227851321505537398888106855012746117 p=134460556242811604004061671529264401215233974442536870999694816691450423689575549530215841622090861571494882591368883283016107051686642467260643894947947473532769025695530343815260424314855023688439603651834585971233941772580950216838838690315383700689885536546289584980534945897919914730948196240662991266027 q=161469718942256895682124261315253003309512855995894840701317251772156087404025170146631429756064534716206164807382734456438092732743677793224010769460318383691408352089793973150914149255603969984103815563896440419666191368964699279209687091969164697704779792586727943470780308857107052647197945528236341228473 phi=(p-1)*(q-1) e = [103231,97117,69557,108533,106979] d=[] for i in e: d.append(gmpy2.invert(i,phi)) print(d)
m=c for i in d: m=gmpy2.powmod(m,i,n) print(long_to_bytes(m))