理论介绍
基本原理
![图片[1],RSA0-1,网络安全爱好者中心-神域博客网](https://img.godyu.com/2024/02/20240214161943932.png?imageView2/0/format/webp/q/75)
欧拉函数
欧拉函数φ(n):是小于n的自然数中与n互质的数的个数
φ(n)的计算方法并不复杂,但是为了得到最后那个公式,需要一步步讨论:第一种:n=1 φ(1) = 1第二种:n是质数 φ(n)=n-1 质数与小于它的每一个数都构成互质关系第三种:n=p^k(p为质数,k为正整数φ(n)=φ(p^k)=p^k-p^(k-1)=p^k*(1-1/p)只有当一个数不包含质数p,才可能与n互质,而包含质数p的数一共有p^(k-1)个,即1*k、2*k、...p^(k-1)*k第四种:n可以分解成两个互质的整数之积φ(n)=φ(p1*p2)=φ(p1)*φ(p2)(中国剩余定理)最终推理:n=p1^k1*p2^k2*p3^k3...pr^kr(任意一个大于1的正整数,都可以写成质数的积)由4得:φ(n)=φ(p1^k1)*φ(p1^k2)...φ(pr^kr)由3得:φ(n)=p1^k1*p2^k2...pr^kr*(1-1/p1)*(1-1/p2)..*(1-1/pr)所以:φ(n)=n*(1-1/p1)*(1-1/p2)*...(1-1/pr)φ(n)的计算方法并不复杂,但是为了得到最后那个公式,需要一步步讨论: 第一种:n=1 φ(1) = 1 第二种:n是质数 φ(n)=n-1 质数与小于它的每一个数都构成互质关系 第三种:n=p^k(p为质数,k为正整数φ(n)=φ(p^k)=p^k-p^(k-1)=p^k*(1-1/p) 只有当一个数不包含质数p,才可能与n互质,而包含质数p的数一共有p^(k-1)个,即1*k、2*k、...p^(k-1)*k 第四种:n可以分解成两个互质的整数之积φ(n)=φ(p1*p2)=φ(p1)*φ(p2)(中国剩余定理) 最终推理: n=p1^k1*p2^k2*p3^k3...pr^kr(任意一个大于1的正整数,都可以写成质数的积) 由4得:φ(n)=φ(p1^k1)*φ(p1^k2)...φ(pr^kr) 由3得:φ(n)=p1^k1*p2^k2...pr^kr*(1-1/p1)*(1-1/p2)..*(1-1/pr) 所以:φ(n)=n*(1-1/p1)*(1-1/p2)*...(1-1/pr)φ(n)的计算方法并不复杂,但是为了得到最后那个公式,需要一步步讨论: 第一种:n=1 φ(1) = 1 第二种:n是质数 φ(n)=n-1 质数与小于它的每一个数都构成互质关系 第三种:n=p^k(p为质数,k为正整数φ(n)=φ(p^k)=p^k-p^(k-1)=p^k*(1-1/p) 只有当一个数不包含质数p,才可能与n互质,而包含质数p的数一共有p^(k-1)个,即1*k、2*k、...p^(k-1)*k 第四种:n可以分解成两个互质的整数之积φ(n)=φ(p1*p2)=φ(p1)*φ(p2)(中国剩余定理) 最终推理: n=p1^k1*p2^k2*p3^k3...pr^kr(任意一个大于1的正整数,都可以写成质数的积) 由4得:φ(n)=φ(p1^k1)*φ(p1^k2)...φ(pr^kr) 由3得:φ(n)=p1^k1*p2^k2...pr^kr*(1-1/p1)*(1-1/p2)..*(1-1/pr) 所以:φ(n)=n*(1-1/p1)*(1-1/p2)*...(1-1/pr)
φ(n)=n*(1-1/p1)*(1-1/p2)*...(1-1/pr)
欧拉定理
a^φ(n)≡1 (mod n)
a和n互质
费马小定理(欧拉定理的特例)
a^(p-1)≡1(mod p)
p是质数,a,p互质
模反元素(逆元)
a*b≡1(mod n)
a,n互质a mod n的逆元是使 a * b mod n = 1 的最小的b
模运算
四则运算:(a + b) % p = (a % p + b % p) % p(a - b) % p = (a % p - b % p) % p(a * b) % p = (a % p * b % p) % pa ^ b % p = ((a % p) ^ b) % p结合律:((a + b) % p + c) = (a + (b + c) % p) % p((a * b) % p * c) = (a * (b * c) % p) % p交换律:(a + b) % p = (b + a) % p(a * b) % p = (b * a) % p分配律:(a + b) % p = (a % p + b % p) % p((a + b) % p * c) % p = ((a * c) % p + (b * c) % p重要定理:若 a ≡ b (mod p),则对于任意的 c,都有(a + c) ≡ (b + c) (mod p)若 a ≡ b (mod p),则对于任意的 c,都有(a * c) ≡ (b * c) (mod p)若 a ≡ b (mod p),c ≡ d (mod p),则:(a + c) ≡ (b + d) (mod p)(a - c) ≡ (b - d) (mod p)(a * c) ≡ (b * d) (mod p)(a / c) ≡ (b / d) (mod p)四则运算: (a + b) % p = (a % p + b % p) % p (a - b) % p = (a % p - b % p) % p (a * b) % p = (a % p * b % p) % p a ^ b % p = ((a % p) ^ b) % p 结合律: ((a + b) % p + c) = (a + (b + c) % p) % p ((a * b) % p * c) = (a * (b * c) % p) % p 交换律: (a + b) % p = (b + a) % p (a * b) % p = (b * a) % p 分配律: (a + b) % p = (a % p + b % p) % p ((a + b) % p * c) % p = ((a * c) % p + (b * c) % p 重要定理: 若 a ≡ b (mod p),则对于任意的 c,都有(a + c) ≡ (b + c) (mod p) 若 a ≡ b (mod p),则对于任意的 c,都有(a * c) ≡ (b * c) (mod p) 若 a ≡ b (mod p),c ≡ d (mod p),则: (a + c) ≡ (b + d) (mod p) (a - c) ≡ (b - d) (mod p) (a * c) ≡ (b * d) (mod p) (a / c) ≡ (b / d) (mod p)四则运算: (a + b) % p = (a % p + b % p) % p (a - b) % p = (a % p - b % p) % p (a * b) % p = (a % p * b % p) % p a ^ b % p = ((a % p) ^ b) % p 结合律: ((a + b) % p + c) = (a + (b + c) % p) % p ((a * b) % p * c) = (a * (b * c) % p) % p 交换律: (a + b) % p = (b + a) % p (a * b) % p = (b * a) % p 分配律: (a + b) % p = (a % p + b % p) % p ((a + b) % p * c) % p = ((a * c) % p + (b * c) % p 重要定理: 若 a ≡ b (mod p),则对于任意的 c,都有(a + c) ≡ (b + c) (mod p) 若 a ≡ b (mod p),则对于任意的 c,都有(a * c) ≡ (b * c) (mod p) 若 a ≡ b (mod p),c ≡ d (mod p),则: (a + c) ≡ (b + d) (mod p) (a - c) ≡ (b - d) (mod p) (a * c) ≡ (b * d) (mod p) (a / c) ≡ (b / d) (mod p)
解释原理
1:c=m^e%N 加密2:m=c^d%N 解密1:c=m^e%N 加密 2:m=c^d%N 解密1:c=m^e%N 加密 2:m=c^d%N 解密
将1带入2: m = (m ^ e % N ) ^ d % N需要证明: m == ( m ^ e % N ) ^ d % N(m^e%N)^d%N=> (m^e)^d%N=> m^(e*d)%N 因为e * d ≡ 1 (mod φ(N))所以e*d=K*φ(N)+1=> (m^(K*φ(N)+1))%N=> (m^(K*φ(N)*m)%N=> ((m^φ(N)^K%N*m)%N=> ((m^φ(N)^K%N*m%N)%N=> ((m^φ(N)%N)^K%N*m%N)%N=> (1^K%N*m%N)%N 欧拉定理:a^φ(n)≡1 mod n=> (m%N)%N=> m%N m<N=> m将1带入2: m = (m ^ e % N ) ^ d % N 需要证明: m == ( m ^ e % N ) ^ d % N (m^e%N)^d%N => (m^e)^d%N => m^(e*d)%N 因为e * d ≡ 1 (mod φ(N))所以e*d=K*φ(N)+1 => (m^(K*φ(N)+1))%N => (m^(K*φ(N)*m)%N => ((m^φ(N)^K%N*m)%N => ((m^φ(N)^K%N*m%N)%N => ((m^φ(N)%N)^K%N*m%N)%N => (1^K%N*m%N)%N 欧拉定理:a^φ(n)≡1 mod n => (m%N)%N => m%N m<N => m将1带入2: m = (m ^ e % N ) ^ d % N 需要证明: m == ( m ^ e % N ) ^ d % N (m^e%N)^d%N => (m^e)^d%N => m^(e*d)%N 因为e * d ≡ 1 (mod φ(N))所以e*d=K*φ(N)+1 => (m^(K*φ(N)+1))%N => (m^(K*φ(N)*m)%N => ((m^φ(N)^K%N*m)%N => ((m^φ(N)^K%N*m%N)%N => ((m^φ(N)%N)^K%N*m%N)%N => (1^K%N*m%N)%N 欧拉定理:a^φ(n)≡1 mod n => (m%N)%N => m%N m<N => m
基本过程
第一步,随机选择两个不相等的质数p和q。第二步,计算p和q的乘积n。第三步,计算n的欧拉函数φ(n)。第四步,随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质。第五步,计算e对于φ(n)的模反元素d。第六步,将n和e封装成公钥,n和d封装成私钥。第一步,随机选择两个不相等的质数p和q。 第二步,计算p和q的乘积n。 第三步,计算n的欧拉函数φ(n)。 第四步,随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质。 第五步,计算e对于φ(n)的模反元素d。 第六步,将n和e封装成公钥,n和d封装成私钥。第一步,随机选择两个不相等的质数p和q。 第二步,计算p和q的乘积n。 第三步,计算n的欧拉函数φ(n)。 第四步,随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质。 第五步,计算e对于φ(n)的模反元素d。 第六步,将n和e封装成公钥,n和d封装成私钥。
RSA算法的可靠性
回顾上面的密钥生成步骤,一共出现六个数字:p,q,n,φ(n),e,d这六个数字之中,公钥用到了两个(n和e),其余四个数字都是不公开的。其中最关键的是d,因为n和d组成了私钥,一旦d泄漏,就等于私钥泄漏。那么,有无可能在已知n和e的情况下,推导出d?(1)ed≡1 (mod φ(n))。只有知道e和φ(n),才能算出d。(2)φ(n)=(p-1)(q-1)。只有知道p和q,才能算出φ(n)。(3)n=pq。只有将n因数分解,才能算出p和q。结论:如果n可以被因数分解,d就可以算出,也就意味着私钥被破解。可是,大整数的因数分解,是一件非常困难的事情。目前,除了暴力破解,还没有发现别的有效方法。维基百科这样写道:“对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法,那么RSA的可靠性就会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA密钥才可能被暴力破解。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要密钥长度足够长,用RSA加密的信息实际上是不能被解破的。”回顾上面的密钥生成步骤,一共出现六个数字:p,q,n,φ(n),e,d 这六个数字之中,公钥用到了两个(n和e),其余四个数字都是不公开的。其中最关键的是d,因为n和d组成了私钥,一旦d泄漏,就等于私钥泄漏。 那么,有无可能在已知n和e的情况下,推导出d? (1)ed≡1 (mod φ(n))。只有知道e和φ(n),才能算出d。 (2)φ(n)=(p-1)(q-1)。只有知道p和q,才能算出φ(n)。 (3)n=pq。只有将n因数分解,才能算出p和q。 结论:如果n可以被因数分解,d就可以算出,也就意味着私钥被破解。 可是,大整数的因数分解,是一件非常困难的事情。目前,除了暴力破解,还没有发现别的有效方法。维基百科这样写道: “对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。 假如有人找到一种快速因数分解的算法,那么RSA的可靠性就会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA密钥才可能被暴力破解。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。 只要密钥长度足够长,用RSA加密的信息实际上是不能被解破的。”回顾上面的密钥生成步骤,一共出现六个数字:p,q,n,φ(n),e,d 这六个数字之中,公钥用到了两个(n和e),其余四个数字都是不公开的。其中最关键的是d,因为n和d组成了私钥,一旦d泄漏,就等于私钥泄漏。 那么,有无可能在已知n和e的情况下,推导出d? (1)ed≡1 (mod φ(n))。只有知道e和φ(n),才能算出d。 (2)φ(n)=(p-1)(q-1)。只有知道p和q,才能算出φ(n)。 (3)n=pq。只有将n因数分解,才能算出p和q。 结论:如果n可以被因数分解,d就可以算出,也就意味着私钥被破解。 可是,大整数的因数分解,是一件非常困难的事情。目前,除了暴力破解,还没有发现别的有效方法。维基百科这样写道: “对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。 假如有人找到一种快速因数分解的算法,那么RSA的可靠性就会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA密钥才可能被暴力破解。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。 只要密钥长度足够长,用RSA加密的信息实际上是不能被解破的。”
基础实战
基础出题脚本
import libnum#生成随机素数p=libnum.generate_prime(1024)q=libnum.generate_prime(1024)e=65537m="flag{20d6e2da95dcc1fa5f5432a436c4be18}"#字符串转数字m=libnum.s2n(m)n=p*qphi_n=(p-1)*(q-1)#求逆元d=libnum.invmod(e,phi_n)c=pow(m,e,n)print("p=",p)print("q=",q)print ("n=",n)print("d=",d)print ("e=",e)print ("c=",c)import libnum #生成随机素数 p=libnum.generate_prime(1024) q=libnum.generate_prime(1024) e=65537 m="flag{20d6e2da95dcc1fa5f5432a436c4be18}" #字符串转数字 m=libnum.s2n(m) n=p*q phi_n=(p-1)*(q-1) #求逆元 d=libnum.invmod(e,phi_n) c=pow(m,e,n) print("p=",p) print("q=",q) print ("n=",n) print("d=",d) print ("e=",e) print ("c=",c)import libnum #生成随机素数 p=libnum.generate_prime(1024) q=libnum.generate_prime(1024) e=65537 m="flag{20d6e2da95dcc1fa5f5432a436c4be18}" #字符串转数字 m=libnum.s2n(m) n=p*q phi_n=(p-1)*(q-1) #求逆元 d=libnum.invmod(e,phi_n) c=pow(m,e,n) print("p=",p) print("q=",q) print ("n=",n) print("d=",d) print ("e=",e) print ("c=",c)
基础解题脚本
已知n,d,e,c求m
import libnumn= 14685532699024100754723222996385121368294636639693750794149020559314539676501066491415844320990799035552463714403031072164829458702780715523923962246149328887690893262271480633736651143634392056066729487305166335857950659680699210683976952113003674104898343893168719508462975991580551696824510044412974267585312807460664570245139015568859112921920860421973308538800641652781742897528769692264955229878206911313791989518088100099218315995549914435278654377368771668058107642713121127495780090852489015591581414806590111818355121157794129813430710822697558144598815860067978324469091074823400715400666808772858128261149d= 10655677501818714057545408290692306276248758047017058020876274084213258239416744966450976471246402284779991562186357882946337721435118045765127426899173581894141706933500094886492805160951008521020815528782559085235105783294876017603112074153984218299742602608478449101819428678878037976091306073545785820932796422483686522431260926680891531210950251782422010888047909274618007401655588566411972291526501884077240225819170340160706732901152519829956055255218835518533347875405883278225018714890042991619568316304958478955576005445279807142753050999269866987221510643119355301877102904394259290548609330522059178100989e= 65537c= 7937297427288435728721973474925856865675225171317301007619581716746999628275946964127516634203401830643076435690247635478297903236185011960902817030042080567027165802992734580344202744697251074454156026031417427325660809453340428989949816426637434868049018580855865080715251672252410696685286047485204432648545886024276695749435709592994477514818763551176789963387889424072650811645828675090859926233585219662579177051353763021116106877502871331756544361402971459889233069752657661921397258845893293005099736406362733668960163109452223071514272504206470939914043855546880424121530822318600645513435826636440478681928m=pow(c, d, n)print(libnum.n2s(m).decode())import libnum n= 14685532699024100754723222996385121368294636639693750794149020559314539676501066491415844320990799035552463714403031072164829458702780715523923962246149328887690893262271480633736651143634392056066729487305166335857950659680699210683976952113003674104898343893168719508462975991580551696824510044412974267585312807460664570245139015568859112921920860421973308538800641652781742897528769692264955229878206911313791989518088100099218315995549914435278654377368771668058107642713121127495780090852489015591581414806590111818355121157794129813430710822697558144598815860067978324469091074823400715400666808772858128261149 d= 10655677501818714057545408290692306276248758047017058020876274084213258239416744966450976471246402284779991562186357882946337721435118045765127426899173581894141706933500094886492805160951008521020815528782559085235105783294876017603112074153984218299742602608478449101819428678878037976091306073545785820932796422483686522431260926680891531210950251782422010888047909274618007401655588566411972291526501884077240225819170340160706732901152519829956055255218835518533347875405883278225018714890042991619568316304958478955576005445279807142753050999269866987221510643119355301877102904394259290548609330522059178100989 e= 65537 c= 7937297427288435728721973474925856865675225171317301007619581716746999628275946964127516634203401830643076435690247635478297903236185011960902817030042080567027165802992734580344202744697251074454156026031417427325660809453340428989949816426637434868049018580855865080715251672252410696685286047485204432648545886024276695749435709592994477514818763551176789963387889424072650811645828675090859926233585219662579177051353763021116106877502871331756544361402971459889233069752657661921397258845893293005099736406362733668960163109452223071514272504206470939914043855546880424121530822318600645513435826636440478681928 m=pow(c, d, n) print(libnum.n2s(m).decode())import libnum n= 14685532699024100754723222996385121368294636639693750794149020559314539676501066491415844320990799035552463714403031072164829458702780715523923962246149328887690893262271480633736651143634392056066729487305166335857950659680699210683976952113003674104898343893168719508462975991580551696824510044412974267585312807460664570245139015568859112921920860421973308538800641652781742897528769692264955229878206911313791989518088100099218315995549914435278654377368771668058107642713121127495780090852489015591581414806590111818355121157794129813430710822697558144598815860067978324469091074823400715400666808772858128261149 d= 10655677501818714057545408290692306276248758047017058020876274084213258239416744966450976471246402284779991562186357882946337721435118045765127426899173581894141706933500094886492805160951008521020815528782559085235105783294876017603112074153984218299742602608478449101819428678878037976091306073545785820932796422483686522431260926680891531210950251782422010888047909274618007401655588566411972291526501884077240225819170340160706732901152519829956055255218835518533347875405883278225018714890042991619568316304958478955576005445279807142753050999269866987221510643119355301877102904394259290548609330522059178100989 e= 65537 c= 7937297427288435728721973474925856865675225171317301007619581716746999628275946964127516634203401830643076435690247635478297903236185011960902817030042080567027165802992734580344202744697251074454156026031417427325660809453340428989949816426637434868049018580855865080715251672252410696685286047485204432648545886024276695749435709592994477514818763551176789963387889424072650811645828675090859926233585219662579177051353763021116106877502871331756544361402971459889233069752657661921397258845893293005099736406362733668960163109452223071514272504206470939914043855546880424121530822318600645513435826636440478681928 m=pow(c, d, n) print(libnum.n2s(m).decode())
已知p,q,e,c求m
import libnump= 178974110759313878895493455207516672882434662571655460770401953730906926302476821805659378622536968418528094957044346203494793341636459433763427491907849563922785749794854266865548657682445692416895365631610849027415100889893466490767087266542637440212533807985124840688092762928583845838066174446047886496977q= 93610871651220602641323046206103959524660743045950590135111801621145944725719667412027010040112514078098465817329474817485502356054795293086881519931215167856745860801666777619204160653243683622930567962804914581845602027547589056026105213437044768786486688576038889017989891165091320977401144724582916902269e= 65537c= 10505609204533893330224001468185225454647695615253006709365840521320011117703729471412769493857753605106376689659952882885215696765275778768339621441610719177208351696489476567331875339672513868473669863672226315682278831184868041476134806131989809014422520472566202048041013413698358733781909446846787304422628166599338803127610040714545537436536348608012176828441837378861024372912755344397449657260043057239911064546424582314518819235470388313710641962070846850292694572345451390561142917224092435026246696084949470913298543523893386679712766629009873176804118782436042080621119334193337953451160118095182279971122n=p*qphi_n=(p-1)*(q-1)#求逆元d=libnum.invmod(e,phi_n)m=pow(c,d,n)print(m)#数字转字节,转字符串print(libnum.n2s(int(m)).decode())import libnum p= 178974110759313878895493455207516672882434662571655460770401953730906926302476821805659378622536968418528094957044346203494793341636459433763427491907849563922785749794854266865548657682445692416895365631610849027415100889893466490767087266542637440212533807985124840688092762928583845838066174446047886496977 q= 93610871651220602641323046206103959524660743045950590135111801621145944725719667412027010040112514078098465817329474817485502356054795293086881519931215167856745860801666777619204160653243683622930567962804914581845602027547589056026105213437044768786486688576038889017989891165091320977401144724582916902269 e= 65537 c= 10505609204533893330224001468185225454647695615253006709365840521320011117703729471412769493857753605106376689659952882885215696765275778768339621441610719177208351696489476567331875339672513868473669863672226315682278831184868041476134806131989809014422520472566202048041013413698358733781909446846787304422628166599338803127610040714545537436536348608012176828441837378861024372912755344397449657260043057239911064546424582314518819235470388313710641962070846850292694572345451390561142917224092435026246696084949470913298543523893386679712766629009873176804118782436042080621119334193337953451160118095182279971122 n=p*q phi_n=(p-1)*(q-1) #求逆元 d=libnum.invmod(e,phi_n) m=pow(c,d,n) print(m) #数字转字节,转字符串 print(libnum.n2s(int(m)).decode())import libnum p= 178974110759313878895493455207516672882434662571655460770401953730906926302476821805659378622536968418528094957044346203494793341636459433763427491907849563922785749794854266865548657682445692416895365631610849027415100889893466490767087266542637440212533807985124840688092762928583845838066174446047886496977 q= 93610871651220602641323046206103959524660743045950590135111801621145944725719667412027010040112514078098465817329474817485502356054795293086881519931215167856745860801666777619204160653243683622930567962804914581845602027547589056026105213437044768786486688576038889017989891165091320977401144724582916902269 e= 65537 c= 10505609204533893330224001468185225454647695615253006709365840521320011117703729471412769493857753605106376689659952882885215696765275778768339621441610719177208351696489476567331875339672513868473669863672226315682278831184868041476134806131989809014422520472566202048041013413698358733781909446846787304422628166599338803127610040714545537436536348608012176828441837378861024372912755344397449657260043057239911064546424582314518819235470388313710641962070846850292694572345451390561142917224092435026246696084949470913298543523893386679712766629009873176804118782436042080621119334193337953451160118095182279971122 n=p*q phi_n=(p-1)*(q-1) #求逆元 d=libnum.invmod(e,phi_n) m=pow(c,d,n) print(m) #数字转字节,转字符串 print(libnum.n2s(int(m)).decode())
暴力分解n的RSA
1.在线查询分解网站
2.使用yafu工具分解
#以分解49为例yafu-x64.exe factor(49)#导入文件进行分解,主要注意文本结尾要换行!!!不然要报错yafu-x64.exe "factor(@)" -batchfile 1.txt#以分解49为例 yafu-x64.exe factor(49) #导入文件进行分解,主要注意文本结尾要换行!!!不然要报错 yafu-x64.exe "factor(@)" -batchfile 1.txt#以分解49为例 yafu-x64.exe factor(49) #导入文件进行分解,主要注意文本结尾要换行!!!不然要报错 yafu-x64.exe "factor(@)" -batchfile 1.txt
3.使用费马小定理
适用于p和q接近的情况
原理
#分解函数def isqrt(n):x = ny = (x + n // x) // 2while y < x:x = yy = (x + n // x) // 2return xdef fermat(n, verbose=True):a = isqrt(n) # int(ceil(n**0.5))b2 = a*a - nb = isqrt(n) # int(b2**0.5)count = 0while b*b != b2:# if verbose:# print('Trying: a=%s b2=%s b=%s' % (a, b2, b))a = a + 1b2 = a*a - nb = isqrt(b2) # int(b2**0.5)count += 1p=a+bq=a-bassert n == p * q# print('a=',a)# print('b=',b)# print('p=',p)# print('q=',q)# print('pq=',p*q)return p, qfermat(n)分解出来后用脚本解密import gmpy2import libnump=q=e=c=n=p*qphi_n=(p-1)*(q-1)#求逆元#d=libnum.invmod(e,phi_n)d=gmpy2.invert(e,phi_n)m=pow(c,d,n)print(m)print(libnum.n2s(int(m)).decode())#分解函数 def isqrt(n): x = n y = (x + n // x) // 2 while y < x: x = y y = (x + n // x) // 2 return x def fermat(n, verbose=True): a = isqrt(n) # int(ceil(n**0.5)) b2 = a*a - n b = isqrt(n) # int(b2**0.5) count = 0 while b*b != b2: # if verbose: # print('Trying: a=%s b2=%s b=%s' % (a, b2, b)) a = a + 1 b2 = a*a - n b = isqrt(b2) # int(b2**0.5) count += 1 p=a+b q=a-b assert n == p * q # print('a=',a) # print('b=',b) # print('p=',p) # print('q=',q) # print('pq=',p*q) return p, q fermat(n) 分解出来后用脚本解密 import gmpy2 import libnum p= q= e= c= n=p*q phi_n=(p-1)*(q-1) #求逆元 #d=libnum.invmod(e,phi_n) d=gmpy2.invert(e,phi_n) m=pow(c,d,n) print(m) print(libnum.n2s(int(m)).decode())#分解函数 def isqrt(n): x = n y = (x + n // x) // 2 while y < x: x = y y = (x + n // x) // 2 return x def fermat(n, verbose=True): a = isqrt(n) # int(ceil(n**0.5)) b2 = a*a - n b = isqrt(n) # int(b2**0.5) count = 0 while b*b != b2: # if verbose: # print('Trying: a=%s b2=%s b=%s' % (a, b2, b)) a = a + 1 b2 = a*a - n b = isqrt(b2) # int(b2**0.5) count += 1 p=a+b q=a-b assert n == p * q # print('a=',a) # print('b=',b) # print('p=',p) # print('q=',q) # print('pq=',p*q) return p, q fermat(n) 分解出来后用脚本解密 import gmpy2 import libnum p= q= e= c= n=p*q phi_n=(p-1)*(q-1) #求逆元 #d=libnum.invmod(e,phi_n) d=gmpy2.invert(e,phi_n) m=pow(c,d,n) print(m) print(libnum.n2s(int(m)).decode())
出题脚本
import libnumimport gmpy2p=libnum.generate_prime(1024)#下一个素数q=gmpy2.next_prime(p)print(gmpy2.is_prime(q))e=65537m="flag{20d6e2da95dcc1fa5f5432a436c4be18}"m=libnum.s2n(m)n=p*qphi_n=(p-1)*(q-1)d=libnum.invmod(e,phi_n)c=pow(m,e,n)print ("p=",p)print ("q=",q)print ("n=",n)print ("e=",e)print ("c=",c)import libnum import gmpy2 p=libnum.generate_prime(1024) #下一个素数 q=gmpy2.next_prime(p) print(gmpy2.is_prime(q)) e=65537 m="flag{20d6e2da95dcc1fa5f5432a436c4be18}" m=libnum.s2n(m) n=p*q phi_n=(p-1)*(q-1) d=libnum.invmod(e,phi_n) c=pow(m,e,n) print ("p=",p) print ("q=",q) print ("n=",n) print ("e=",e) print ("c=",c)import libnum import gmpy2 p=libnum.generate_prime(1024) #下一个素数 q=gmpy2.next_prime(p) print(gmpy2.is_prime(q)) e=65537 m="flag{20d6e2da95dcc1fa5f5432a436c4be18}" m=libnum.s2n(m) n=p*q phi_n=(p-1)*(q-1) d=libnum.invmod(e,phi_n) c=pow(m,e,n) print ("p=",p) print ("q=",q) print ("n=",n) print ("e=",e) print ("c=",c)
解题脚本
import gmpy2import libnumdef isqrt(n):x = ny = (x + n // x) // 2while y < x:x = yy = (x + n // x) // 2return xdef fermat(n, verbose=True):a = isqrt(n) # int(ceil(n**0.5))b2 = a*a - nb = isqrt(n) # int(b2**0.5)count = 0while b*b != b2:# if verbose:# print('Trying: a=%s b2=%s b=%s' % (a, b2, b))a = a + 1b2 = a*a - nb = isqrt(b2) # int(b2**0.5)count += 1p=a+bq=a-bassert n == p * q# print('a=',a)# print('b=',b)print('p=',p)print('q=',q)# print('pq=',p*q)return p, qn= 11236396438945464079176717143196471087880430124798640194523124584883161483744355761881720924798661332027501424643154414538029585287580122761405974427818841257794157497994556608202723391478027760181705924317533420305444809223444128034654367210331137068958693840582892819495487826045956577156074156668942232139402108462349340352898572481115406698318121299787982873916502591396884489682255184448165523604671743400422220149772905676655777228607948091675612455989601008858361759327370403306760674195506394280387024357322586732298060169962426894360775981877169895632927906390632063530920611197753716095903307467004289983267e= 65537c= 4260482466101011731957430920901406417434306478040387371588613512063428441001754753741853444857207349755032658064826592770143368278573527632514794087007140974732031358793249329430363014561312271335226315065519570861993052432656879088776144909638480994662696119431870831156129142403063675855781198930583825083362703887688501680905266707624440432914989795886392952354713859444836529227033324455920455610359249535012999943891644938239837207994673190694512955995798836266797112432609992164908679997257920566918693544746179908166741635316261624634351348613130319346356388546672516037747806222134853885202448682842353199133pq=fermat(n) #通过脚本或工具分解出q,pp=pq[0]q=pq[1]phi_n=(p-1)*(q-1)#求逆元#d=libnum.invmod(e,phi_n)d=gmpy2.invert(e,phi_n)m=pow(c,d,n)print(m)print(libnum.n2s(int(m)).decode())import gmpy2 import libnum def isqrt(n): x = n y = (x + n // x) // 2 while y < x: x = y y = (x + n // x) // 2 return x def fermat(n, verbose=True): a = isqrt(n) # int(ceil(n**0.5)) b2 = a*a - n b = isqrt(n) # int(b2**0.5) count = 0 while b*b != b2: # if verbose: # print('Trying: a=%s b2=%s b=%s' % (a, b2, b)) a = a + 1 b2 = a*a - n b = isqrt(b2) # int(b2**0.5) count += 1 p=a+b q=a-b assert n == p * q # print('a=',a) # print('b=',b) print('p=',p) print('q=',q) # print('pq=',p*q) return p, q n= 11236396438945464079176717143196471087880430124798640194523124584883161483744355761881720924798661332027501424643154414538029585287580122761405974427818841257794157497994556608202723391478027760181705924317533420305444809223444128034654367210331137068958693840582892819495487826045956577156074156668942232139402108462349340352898572481115406698318121299787982873916502591396884489682255184448165523604671743400422220149772905676655777228607948091675612455989601008858361759327370403306760674195506394280387024357322586732298060169962426894360775981877169895632927906390632063530920611197753716095903307467004289983267 e= 65537 c= 4260482466101011731957430920901406417434306478040387371588613512063428441001754753741853444857207349755032658064826592770143368278573527632514794087007140974732031358793249329430363014561312271335226315065519570861993052432656879088776144909638480994662696119431870831156129142403063675855781198930583825083362703887688501680905266707624440432914989795886392952354713859444836529227033324455920455610359249535012999943891644938239837207994673190694512955995798836266797112432609992164908679997257920566918693544746179908166741635316261624634351348613130319346356388546672516037747806222134853885202448682842353199133 pq=fermat(n) #通过脚本或工具分解出q,p p=pq[0] q=pq[1] phi_n=(p-1)*(q-1) #求逆元 #d=libnum.invmod(e,phi_n) d=gmpy2.invert(e,phi_n) m=pow(c,d,n) print(m) print(libnum.n2s(int(m)).decode())import gmpy2 import libnum def isqrt(n): x = n y = (x + n // x) // 2 while y < x: x = y y = (x + n // x) // 2 return x def fermat(n, verbose=True): a = isqrt(n) # int(ceil(n**0.5)) b2 = a*a - n b = isqrt(n) # int(b2**0.5) count = 0 while b*b != b2: # if verbose: # print('Trying: a=%s b2=%s b=%s' % (a, b2, b)) a = a + 1 b2 = a*a - n b = isqrt(b2) # int(b2**0.5) count += 1 p=a+b q=a-b assert n == p * q # print('a=',a) # print('b=',b) print('p=',p) print('q=',q) # print('pq=',p*q) return p, q n= 11236396438945464079176717143196471087880430124798640194523124584883161483744355761881720924798661332027501424643154414538029585287580122761405974427818841257794157497994556608202723391478027760181705924317533420305444809223444128034654367210331137068958693840582892819495487826045956577156074156668942232139402108462349340352898572481115406698318121299787982873916502591396884489682255184448165523604671743400422220149772905676655777228607948091675612455989601008858361759327370403306760674195506394280387024357322586732298060169962426894360775981877169895632927906390632063530920611197753716095903307467004289983267 e= 65537 c= 4260482466101011731957430920901406417434306478040387371588613512063428441001754753741853444857207349755032658064826592770143368278573527632514794087007140974732031358793249329430363014561312271335226315065519570861993052432656879088776144909638480994662696119431870831156129142403063675855781198930583825083362703887688501680905266707624440432914989795886392952354713859444836529227033324455920455610359249535012999943891644938239837207994673190694512955995798836266797112432609992164908679997257920566918693544746179908166741635316261624634351348613130319346356388546672516037747806222134853885202448682842353199133 pq=fermat(n) #通过脚本或工具分解出q,p p=pq[0] q=pq[1] phi_n=(p-1)*(q-1) #求逆元 #d=libnum.invmod(e,phi_n) d=gmpy2.invert(e,phi_n) m=pow(c,d,n) print(m) print(libnum.n2s(int(m)).decode())
RSA密钥生成与读取
安装pycryptodome模块
公钥生成
from Crypto.PublicKey import RSAp= 787228223375328491232514653709q= 814212346998672554509751911073n= 640970939378021470187479083920100737340912672709639557619757d= 590103645243332826117029128695341159496883001869370080307201e= 65537rsa_components = (n, e)keypair = RSA.construct(rsa_components)with open('pubckey.pem', 'wb') as f :f.write(keypair.exportKey())from Crypto.PublicKey import RSA p= 787228223375328491232514653709 q= 814212346998672554509751911073 n= 640970939378021470187479083920100737340912672709639557619757 d= 590103645243332826117029128695341159496883001869370080307201 e= 65537 rsa_components = (n, e) keypair = RSA.construct(rsa_components) with open('pubckey.pem', 'wb') as f : f.write(keypair.exportKey())from Crypto.PublicKey import RSA p= 787228223375328491232514653709 q= 814212346998672554509751911073 n= 640970939378021470187479083920100737340912672709639557619757 d= 590103645243332826117029128695341159496883001869370080307201 e= 65537 rsa_components = (n, e) keypair = RSA.construct(rsa_components) with open('pubckey.pem', 'wb') as f : f.write(keypair.exportKey())
私钥生成
from Crypto.PublicKey import RSAp= 787228223375328491232514653709q= 814212346998672554509751911073n= 640970939378021470187479083920100737340912672709639557619757d= 590103645243332826117029128695341159496883001869370080307201e= 65537rsa_components = (n,e,d,p,q)keypair = RSA.construct(rsa_components)with open('private1.pem', 'wb') as f :f.write(keypair.exportKey())from Crypto.PublicKey import RSA p= 787228223375328491232514653709 q= 814212346998672554509751911073 n= 640970939378021470187479083920100737340912672709639557619757 d= 590103645243332826117029128695341159496883001869370080307201 e= 65537 rsa_components = (n,e,d,p,q) keypair = RSA.construct(rsa_components) with open('private1.pem', 'wb') as f : f.write(keypair.exportKey())from Crypto.PublicKey import RSA p= 787228223375328491232514653709 q= 814212346998672554509751911073 n= 640970939378021470187479083920100737340912672709639557619757 d= 590103645243332826117029128695341159496883001869370080307201 e= 65537 rsa_components = (n,e,d,p,q) keypair = RSA.construct(rsa_components) with open('private1.pem', 'wb') as f : f.write(keypair.exportKey())
公钥读取
from Crypto.PublicKey import RSAwith open("pubckey.pem","rb") as f:key = RSA.import_key(f.read())print('n = %d' % key.n)print('e = %d' % key.e)from Crypto.PublicKey import RSA with open("pubckey.pem","rb") as f: key = RSA.import_key(f.read()) print('n = %d' % key.n) print('e = %d' % key.e)from Crypto.PublicKey import RSA with open("pubckey.pem","rb") as f: key = RSA.import_key(f.read()) print('n = %d' % key.n) print('e = %d' % key.e)
私钥读取
from Crypto.PublicKey import RSAwith open("private1.pem","rb") as f:key = RSA.import_key(f.read())print('n = %d' % key.n)print('e = %d' % key.e)print('d = %d' % key.d)print('p = %d' % key.p)print('q = %d' % key.q)from Crypto.PublicKey import RSA with open("private1.pem","rb") as f: key = RSA.import_key(f.read()) print('n = %d' % key.n) print('e = %d' % key.e) print('d = %d' % key.d) print('p = %d' % key.p) print('q = %d' % key.q)from Crypto.PublicKey import RSA with open("private1.pem","rb") as f: key = RSA.import_key(f.read()) print('n = %d' % key.n) print('e = %d' % key.e) print('d = %d' % key.d) print('p = %d' % key.p) print('q = %d' % key.q)
出题脚本-基于N分解的题目
import libnumimport gmpy2from Crypto.PublicKey import RSAp=libnum.generate_prime(1024)#下一个素数q=int(gmpy2.next_prime(p))e=65537m="flag{a272722c1db834353ea3ce1d9c71feca}"m=libnum.s2n(m)n=p*qc=pow(m,e,n)flag_c=libnum.n2s(c)rsa_components = (n, e)keypair = RSA.construct(rsa_components)with open('pubckey1.pem', 'wb') as f :f.write(keypair.exportKey())with open("flag.txt","wb") as f:f.write(flag_c)import libnum import gmpy2 from Crypto.PublicKey import RSA p=libnum.generate_prime(1024) #下一个素数 q=int(gmpy2.next_prime(p)) e=65537 m="flag{a272722c1db834353ea3ce1d9c71feca}" m=libnum.s2n(m) n=p*q c=pow(m,e,n) flag_c=libnum.n2s(c) rsa_components = (n, e) keypair = RSA.construct(rsa_components) with open('pubckey1.pem', 'wb') as f : f.write(keypair.exportKey()) with open("flag.txt","wb") as f: f.write(flag_c)import libnum import gmpy2 from Crypto.PublicKey import RSA p=libnum.generate_prime(1024) #下一个素数 q=int(gmpy2.next_prime(p)) e=65537 m="flag{a272722c1db834353ea3ce1d9c71feca}" m=libnum.s2n(m) n=p*q c=pow(m,e,n) flag_c=libnum.n2s(c) rsa_components = (n, e) keypair = RSA.construct(rsa_components) with open('pubckey1.pem', 'wb') as f : f.write(keypair.exportKey()) with open("flag.txt","wb") as f: f.write(flag_c)
解题脚本
import libnumimport gmpy2from Crypto.PublicKey import RSAdef isqrt(n):x = ny = (x + n // x) // 2while y < x:x = yy = (x + n // x) // 2return xdef fermat(n, verbose=True):a = isqrt(n) # int(ceil(n**0.5))b2 = a*a - nb = isqrt(n) # int(b2**0.5)count = 0while b*b != b2:# if verbose:# print('Trying: a=%s b2=%s b=%s' % (a, b2, b))a = a + 1b2 = a*a - nb = isqrt(b2) # int(b2**0.5)count += 1p=a+bq=a-bassert n == p * q# print('a=',a)# print('b=',b)# print('p=',p)# print('q=',q)# print('pq=',p*q)return p, qwith open("pubckey1.pem","rb") as f:key = RSA.import_key(f.read())n=key.ne=key.ewith open("flag.txt","rb") as f:c=f.read()c=libnum.s2n(c)#费马分解n1=fermat(n)p=n1[0]q=n1[1]phi_n=(p-1)*(q-1)#求逆元d=libnum.invmod(e,phi_n)m=pow(c,d,n)print(m)print(libnum.n2s(int(m)).decode())import libnum import gmpy2 from Crypto.PublicKey import RSA def isqrt(n): x = n y = (x + n // x) // 2 while y < x: x = y y = (x + n // x) // 2 return x def fermat(n, verbose=True): a = isqrt(n) # int(ceil(n**0.5)) b2 = a*a - n b = isqrt(n) # int(b2**0.5) count = 0 while b*b != b2: # if verbose: # print('Trying: a=%s b2=%s b=%s' % (a, b2, b)) a = a + 1 b2 = a*a - n b = isqrt(b2) # int(b2**0.5) count += 1 p=a+b q=a-b assert n == p * q # print('a=',a) # print('b=',b) # print('p=',p) # print('q=',q) # print('pq=',p*q) return p, q with open("pubckey1.pem","rb") as f: key = RSA.import_key(f.read()) n=key.n e=key.e with open("flag.txt","rb") as f: c=f.read() c=libnum.s2n(c) #费马分解 n1=fermat(n) p=n1[0] q=n1[1] phi_n=(p-1)*(q-1) #求逆元 d=libnum.invmod(e,phi_n) m=pow(c,d,n) print(m) print(libnum.n2s(int(m)).decode())import libnum import gmpy2 from Crypto.PublicKey import RSA def isqrt(n): x = n y = (x + n // x) // 2 while y < x: x = y y = (x + n // x) // 2 return x def fermat(n, verbose=True): a = isqrt(n) # int(ceil(n**0.5)) b2 = a*a - n b = isqrt(n) # int(b2**0.5) count = 0 while b*b != b2: # if verbose: # print('Trying: a=%s b2=%s b=%s' % (a, b2, b)) a = a + 1 b2 = a*a - n b = isqrt(b2) # int(b2**0.5) count += 1 p=a+b q=a-b assert n == p * q # print('a=',a) # print('b=',b) # print('p=',p) # print('q=',q) # print('pq=',p*q) return p, q with open("pubckey1.pem","rb") as f: key = RSA.import_key(f.read()) n=key.n e=key.e with open("flag.txt","rb") as f: c=f.read() c=libnum.s2n(c) #费马分解 n1=fermat(n) p=n1[0] q=n1[1] phi_n=(p-1)*(q-1) #求逆元 d=libnum.invmod(e,phi_n) m=pow(c,d,n) print(m) print(libnum.n2s(int(m)).decode())
自动生成密钥并加密
from Crypto.Cipher import PKCS1_v1_5from Crypto import Randomfrom Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_OAEPrandom_generator = Random.new().readrsa = RSA.generate(2048, random_generator)# 生成私钥private_key = rsa.exportKey()# print(private_key.decode('utf-8'))with open('rsa_private_key.pem', 'wb')as f:f.write(private_key)# 生成公钥public_key = rsa.publickey().exportKey()# print(public_key.decode('utf-8'))with open('rsa_public_key.pem', 'wb')as f:f.write(public_key)#测试用密钥加密public_key = RSA.importKey(public_key)msg='flag'pk = PKCS1_v1_5.new(public_key)encrypt_text = pk.encrypt(msg.encode())print(encrypt_text)#测试密钥解密private_key = RSA.importKey(private_key)pk = PKCS1_v1_5.new(private_key)msg = pk.decrypt(encrypt_text,0)print(msg)#两种标准rsa_components = (n, e, int(d), p, q)arsa = RSA.construct(rsa_components)rsakey = RSA.importKey(arsa.exportKey())rsakey = PKCS1_OAEP.new(rsakey)decrypted = rsakey.decrypt(c)print(decrypted)from Crypto.Cipher import PKCS1_v1_5 from Crypto import Random from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP random_generator = Random.new().read rsa = RSA.generate(2048, random_generator) # 生成私钥 private_key = rsa.exportKey() # print(private_key.decode('utf-8')) with open('rsa_private_key.pem', 'wb')as f: f.write(private_key) # 生成公钥 public_key = rsa.publickey().exportKey() # print(public_key.decode('utf-8')) with open('rsa_public_key.pem', 'wb')as f: f.write(public_key) #测试用密钥加密 public_key = RSA.importKey(public_key) msg='flag' pk = PKCS1_v1_5.new(public_key) encrypt_text = pk.encrypt(msg.encode()) print(encrypt_text) #测试密钥解密 private_key = RSA.importKey(private_key) pk = PKCS1_v1_5.new(private_key) msg = pk.decrypt(encrypt_text,0) print(msg) #两种标准 rsa_components = (n, e, int(d), p, q) arsa = RSA.construct(rsa_components) rsakey = RSA.importKey(arsa.exportKey()) rsakey = PKCS1_OAEP.new(rsakey) decrypted = rsakey.decrypt(c) print(decrypted)from Crypto.Cipher import PKCS1_v1_5 from Crypto import Random from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP random_generator = Random.new().read rsa = RSA.generate(2048, random_generator) # 生成私钥 private_key = rsa.exportKey() # print(private_key.decode('utf-8')) with open('rsa_private_key.pem', 'wb')as f: f.write(private_key) # 生成公钥 public_key = rsa.publickey().exportKey() # print(public_key.decode('utf-8')) with open('rsa_public_key.pem', 'wb')as f: f.write(public_key) #测试用密钥加密 public_key = RSA.importKey(public_key) msg='flag' pk = PKCS1_v1_5.new(public_key) encrypt_text = pk.encrypt(msg.encode()) print(encrypt_text) #测试密钥解密 private_key = RSA.importKey(private_key) pk = PKCS1_v1_5.new(private_key) msg = pk.decrypt(encrypt_text,0) print(msg) #两种标准 rsa_components = (n, e, int(d), p, q) arsa = RSA.construct(rsa_components) rsakey = RSA.importKey(arsa.exportKey()) rsakey = PKCS1_OAEP.new(rsakey) decrypted = rsakey.decrypt(c) print(decrypted)
THE END
- 最新
- 最热
只看作者