数论基础

素数

1.定义: 一个大于1的自然数,除了1和它本身外,不能被其他自然数整除(除0以外)的数称之为素数(质数);否则称为合数。

如:3×4 = 12,不是素数。11除了等于11×1以外,不能表示为其它任何两个整数的乘积,所以11是一个素数。

2.关于素数的事实:

(1)如果p是素数,且p | ab(表示ab能被p整除),则p | a或 p | b ,即p 至少整除a与b中的一个。

(2)算术基本定理:任何一个大于1的自然数 ,如果N不为质数,都可以唯一分解成有限个质数的乘积,即

(3)素数有无穷多个。

最大公约数与最小公倍数

1.最大公约数

定义:几个数公有的约数,叫做这几个数的公约数,其中最大的一个叫做这几个数的最大公约数。数学上,a和b的最大公约数记为(a, b),编程中,计算两个数最大公约数的方法通常记为gcd(a,b)

2.最小公倍数

定义:几个数公有的倍数,叫做这几个数的公倍数,其中最小的一个叫做这几个数的最小公倍数。数学上,a和b的最小公倍数记为[a,b],编程中,计算两个数最小公倍数的方法通常记为lcm(a,b)

欧拉函数

1.定义: 在数论中,对正整数n,欧拉函数φ(n)是小于或等于n的正整数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为φ函数(由高斯所命名)或是欧拉总计函数。例如:φ(8) = 4 ,因为1,3,5,7均与8互质。

2.性质:

欧拉函数是积性函数——若m,n互质,φ(mn)=φ(m)φ(n)

特殊性质:当n为奇数时,φ(2n)=φ(n)

欧几里得(Euclid)算法

1.定义: 欧几里得算法又称为辗转相除法,用于求两个数的最大公约数。基于如下原理:两个整数的最大公约数等于其中较小的数和两数相除余数的最大公约数,即GCD(x,y) = GCD(y,x mod y) ,x>y。

2.代码实现:

def GCD(x, y):|if(y==0):return xelse:return GCD(y,x %y)
from gmpy2 import*
m = gcd(a,b)
#from Crypto.Util. number import*
#m = GCD(a, b)

扩展欧几里得算法

1.定理: 扩展欧几里德算法是欧几里得算法的扩展。若a和b为正整数,则存在整数x,y使得gcd(a,b)=ax+by;换句话说gcd(a,b)可以表示为a,b的整洗数线性组合。
例如:gcd(6,14)=2,而2=(-2)* 6+1 *14.

2.代码实现:

from gmpy2 import*
x=17
y = 65537
#扩展欧几里得算法
s = gcdext(x,y)
#返回元组tuple,满足s[1]*x+s[2]*y = 1
print(s)
#输出: (mpz(1), mpz(30841), mpz(-8))
print(s[1]*x+s[2]*y)
#输出: 1

同余

1.定义: 设a,b是整数,n≠0,如果n|(a-b),则称a和b模n同余,记为a≡b(mod n),整数n称为模数。由于n|(a-b) 等价于 -n|(a-b),所以a≡b(mod n) 与 a≡b(mod (-n))等价。因此,一般我们总假定模数n≥1。

2.性质1:

(1)自反性:a ≡ a (mod m)

(2)对称性:a ≡ b (mod m),↔b ≡ c (mod m) ↔a ≡ c (mod m)

(3)保持基本运算:

模运算

1.定义: a模n的运算给出了a对模n的余数,这种运算称为模运算。注意:模运算的结果是从0到n-1的一个整数。

2.性质: 模运算就像普通的运算一样,它是可交换、可结合、可分配的。而且,对每一个中间结果进行模m运算后再进行模m运算,其作用与先进行全部运算,然后再进行模m运算所得到的结果是一样的。

(a+b)mod m=((a mod m)+(b mod m)) mod m

(a-b)mod m=((a mod m)-(b mod m)) mod m

(a×b)mod m=((a mod m) ×(b mod m)) mod m

(a×(b+c))mod m=((a×b) mod m+(a×c) mod m) mod m

3.用途:

(1)用于判断一个数是否能被另一个数整除。对 2 取模即可判断整数的奇偶性;从 2 到 n-1 取模则可判断一个数是否为质数。
(2)进制之间的转换。
(3)用于求取最大公约数的辗转相除法使用取模运算。
(4)密码学中的应用:从古老的凯撒密码到现代常用的RSA、椭圆曲线密码,它们的实现过程均使用了取模运算。

模逆元

1.定义: 模逆元也称为模倒数,或者模逆元。

一整数a对同余n之模逆元是指满足以下公式的整数 b

2.求解方法:

(1)扩展欧几里得算法:设exgcd(a,n)为扩展欧几里得算法的函数,则可得到ax+ny=g,g是a,n的最大公因数。若g=1,则该模逆元存在;若g≠1,则该模逆元不存在。

(2)欧拉定理:欧拉定理证明当a,n为两个互素的正整数时,则有aφ(n)≡1(modn),φ(n)为欧拉函数,其中 aφ(n)-1即为a关于模n之模逆元

中国剩余定理

中国剩余定理给出了以下的一元线性同余方程组有解的判定条件,并用构造法给出了在有解情况下解的具体形式。

中国剩余定理说明:假设整数m1, m2, … , mn其中任两数互质,则对任意的整数:a1, a2, … , an,上述一元线性同余方程组有解,并且通解可以用如下方式构造得到:

RSA算法

RSA算法简介

RSA攻击方法

思维导图

常见题型

1.模数分解

题目链接(buu平台)

from flag import FLAG
from Cryptodome.Util.number import *
import gmpy2
import randome=65537
p = getPrime(512)
q = int(gmpy2.next_prime(p))
n = p*q
m = bytes_to_long(FLAG)
c = pow(m,e,n)
print(n)
print(c)
# n=177606504836499246970959030226871608885969321778211051080524634084516973331441644993898029573612290095853069264036530459253652875586267946877831055147546910227100566496658148381834683037366134553848011903251252726474047661274223137727688689535823533046778793131902143444408735610821167838717488859902242863683
# c=1457390378511382354771000540945361168984775052693073641682375071407490851289703070905749525830483035988737117653971428424612332020925926617395558868160380601912498299922825914229510166957910451841730028919883807634489834128830801407228447221775264711349928156290102782374379406719292116047581560530382210049

题目为最基础的RSA加密,其中p q为相邻的素数。可以用yafu分解


基础RSA解密:

n=177606504836499246970959030226871608885969321778211051080524634084516973331441644993898029573612290095853069264036530459253652875586267946877831055147546910227100566496658148381834683037366134553848011903251252726474047661274223137727688689535823533046778793131902143444408735610821167838717488859902242863683
c=1457390378511382354771000540945361168984775052693073641682375071407490851289703070905749525830483035988737117653971428424612332020925926617395558868160380601912498299922825914229510166957910451841730028919883807634489834128830801407228447221775264711349928156290102782374379406719292116047581560530382210049
e=65537
p = 13326909050357447643526585836833969378078147057723054701432842192988717649385731430095055622303549577233495793715580004801634268505725255565021519817179293
q = 13326909050357447643526585836833969378078147057723054701432842192988717649385731430095055622303549577233495793715580004801634268505725255565021519817179231
from Crypto.Util.number import *
phi=(p-1)*(q-1)
d=inverse(e,phi)
m=pow(c,d,n)
print(long_to_bytes(m))
# actf{p_and_q_should_not_be_so_close_in_value}

2.n有相同的质因数

题目链接(buu平台)

题面:一份秘密发送给两个人不太好吧,那我各自加密一次好啦~~~
素数生成好慢呀
偷个懒也……不会有问题的吧?

附件:
public1.pub
public2.pub
flag_encry1
flag_encry2

首先尝试取出两份公钥文件的n,e,测试发现n1 n2有公约数,正好印证了题面给的懒得生成素数,所以共用了其中一个素数。

求解公约数即可:

from Crypto.PublicKey import RSA
import gmpy2
from Crypto.Util.number import *
f=open("public1.pub","r")
rsa1=RSA.import_key(f.read())
n1=rsa1.n
e1=rsa1.e
f.close()
f=open("public2.pub","r")
rsa2=RSA.import_key(f.read())
n2=rsa2.n
e2=rsa2.e
f.close()
#print(n1,e1)
#print(n2,e2)
p=gmpy2.gcd(n1,n2)
q=n2//p
assert(p*q==n2)
phi=(p-1)*(q-1)
d=gmpy2.invert(e2,phi)
c_bytes=open("flag_encry2","rb").read()
c=bytes_to_long(c_bytes)
m=pow(c,d,n2)
print(long_to_bytes(m))
#afctf{You_Know_0p3u55I}

3.共模攻击

题目链接(BUU平台)

hint.py如下:

from gmpy2 import *
from Crypto.Util.number import *
from secret import hintm = bytes_to_long(hint)
p = getPrime(256)
c = pow(m, 256, p)
print(p)p, q = getPrime(256), getPrime(256)
n = p * q
e1, e2 = getPrime(32), getPrime(32)
c1, c2 = pow(c, e1, n), pow(c, e2, n)
print(n)
print(e1, c1)
print(e2, c2)'''
107316975771284342108362954945096489708900302633734520943905283655283318535709
6807492006219935335233722232024809784434293293172317282814978688931711423939629682224374870233587969960713638310068784415474535033780772766171320461281579
2303413961 1754421169036191391717309256938035960912941109206872374826444526733030696056821731708193270151759843780894750696642659795452787547355043345348714129217723
2622163991 1613454015951555289711148366977297613624544025937559371784736059448454437652633847111272619248126613500028992813732842041018588707201458398726700828844249
'''

task.py如下:

from gmpy2 import *
from Crypto.Util.number import *
from secret import flagflag = flag.strip(b"npuctf{").strip(b"}")
m = bytes_to_long(flag)p, q = getPrime(512), getPrime(512)
n = p * q
e1, e2 = p, q
c1, c2 = pow(m, e1, n), pow(m, e2, n)print(n)
print(c1)
print(c2)'''
128205304743751985889679351195836799434324346996129753896234917982647254577214018524580290192396070591032007818847697193260130051396080104704981594190602854241936777324431673564677900773992273463534717009587530152480725448774018550562603894883079711995434332008363470321069097619786793617099517770260029108149
96860654235275202217368130195089839608037558388884522737500611121271571335123981588807994043800468529002147570655597610639680977780779494880330669466389788497046710319213376228391138021976388925171307760030058456934898771589435836261317283743951614505136840364638706914424433566782044926111639955612412134198
9566853166416448316408476072940703716510748416699965603380497338943730666656667456274146023583837768495637484138572090891246105018219222267465595710692705776272469703739932909158740030049375350999465338363044226512016686534246611049299981674236577960786526527933966681954486377462298197949323271904405241585
'''

共模攻击,用扩展欧几里得算法求出c。

原理:当GCD(e1, e2) == 1时,由扩展欧几里得算法得,存在s1, s2使 e1s1 + e2s2 = 1,m = pow(m, e1s1 + e2s2, n),而pow(m, e1s1 + e2s2, n) = pow(m, e1s1, n) * pow(m, e2s2, n) = pow(c1, s1, n) * pow(c2, s2, n)

由c和p可以求得m。得到c后,根据表达式:c = m256 mod p,可以借助Python的sympy库nthroot_mod方法,最终由m得到hint:# m =“m.bit_length() < 400”

from gmpy2 import*
from sympy import*
from Crypto.Util.number import *
p = 107316975771284342108362954945096489708900302633734520943905283655283318535709e1 = 2303413961
c1 = 1754421169036191391717309256938035960912941109206872374826444526733030696056821731708193270151759843780894750696642659795452787547355043345348714129217723e2 = 2622163991
c2 = 1613454015951555289711148366977297613624544025937559371784736059448454437652633847111272619248126613500028992813732842041018588707201458398726700828844249
n =  6807492006219935335233722232024809784434293293172317282814978688931711423939629682224374870233587969960713638310068784415474535033780772766171320461281579s = gcdext(e1,e2)
c = pow(c1,s[1],n)*pow(c2,s[2],n) % n
print(c)
#c = 19384002358725759679198917686763310349050988223627625096050800369760484237557m = nthroot_mod(c,256,p)
print(long_to_bytes(m))# m ="m.bit_length() < 400"

参考博客
求m:

from Crypto.Util.number import*n = 128205304743751985889679351195836799434324346996129753896234917982647254577214018524580290192396070591032007818847697193260130051396080104704981594190602854241936777324431673564677900773992273463534717009587530152480725448774018550562603894883079711995434332008363470321069097619786793617099517770260029108149
c1 = 96860654235275202217368130195089839608037558388884522737500611121271571335123981588807994043800468529002147570655597610639680977780779494880330669466389788497046710319213376228391138021976388925171307760030058456934898771589435836261317283743951614505136840364638706914424433566782044926111639955612412134198
c2 = 9566853166416448316408476072940703716510748416699965603380497338943730666656667456274146023583837768495637484138572090891246105018219222267465595710692705776272469703739932909158740030049375350999465338363044226512016686534246611049299981674236577960786526527933966681954486377462298197949323271904405241585a = c1+c2
b = c1*c2print(a)
print(b)# a = 106427507401691650533776606268030543324548306805584488340881108460215302001780649045082140067384306297497785054794169701530927082798998717147796265177082494273319180022953309137549878052025764276170773098393102683446915458123682447310617265418188192465923366892572673596378919944244343124060963227516817375783
# b = 926651656671911333597022401968870409343942400492881255142377951759176631494915016941991504123810265329862246592861145719213675502795378053564904818765377025096483601036025012267103260702787555612216755188521913405305861451125814149409508425602231670292131422273268728629782633354498648021859614223672123489318899205627785426402597996319440198218774038390809403281952702730883306007226797632389267386912707857093556335846269954270572920361347019614365402744026533713442449916555425678184406380167614011131702418493073759816310890056281917310110034453007210415242707924141697749818907383248545179118594511927630223830flag = 4242839043019782000788118887372132807371568279472499477998758466224002905442227156537788110520335652385855
print(long_to_bytes(flag))
# verrrrrrry_345yyyyyyy_rsaaaaaaa_righttttttt?

【笔记】公钥密码学之RSA相关推荐

  1. 【现代密码学原理】——公钥密码学与RSA(学习笔记)

  2. 【学习笔记】密码学入门(2) 单向散列函数,消息认证码,数字签名,证书

    [学习笔记]密码学入门(2) 单向散列函数,消息认证码,数字签名,证书 学习笔记 2 – 混合密码系统 在密码学入门(1)中提到了基本的密码形式,对称密码和公钥密码以及混合密码系统. 这一部分将学习到 ...

  3. 【笔记】密码学与安全技术概要总结(一)

      工程领域从来没有黑科技:密码学不仅是工程.   密码学和安全领域所涉及的知识体系十分繁杂,本文简述密码学领域中跟区块链相关的一些基础知识,包括Hash算法与数字摘要.加密算法.数字签名.数字证书. ...

  4. 密码学:RSA加密算法详解

    概述 本文旨在说明RSA加密算法的原理及实现,而其相关的数学部分的证明则不是本文内容. 版权说明 著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:Q-WHai 发表日期: ...

  5. 密码学之RSA加密原理解析

      密码学是指研究信息加密,破解密码的技术科学.密码学的起源可追溯到2000年前.而当今的密码学是以数学为基础的.   密码学的历史大致可以追溯到两千年前,相传古罗马名将凯撒大帝为了防止敌方截获情报, ...

  6. 公钥密码学中的公钥和私钥

    公钥密码学解释:它是什么? 公钥基础设施 (PKI) 用于管理互联网通信中的身份和安全性. 启用 PKI 的核心技术是公钥密码术,这是一种依赖于使用两个相关密钥(公钥和私钥)的加密机制. 这两个密钥一 ...

  7. 公钥密码体制之RSA

    记一次密码学上课所学的公钥密码体制学习.从一开始的古典密码到流密码再是分组密码,再是现在的公钥密码体制. 产生原因 公钥密码体制的产生主要是因为两个方面的原因:一是由于常规的密钥密码体制的密钥分配问题 ...

  8. 公钥密码学中的简单数学基础

    公钥密码学中的简单数学基础 本文基于<深入浅出密码学>第六章以及Paillier中使用到的相关数学知识进行总结,并计划不断更新 逆元 介绍 注意:不是所有的元素都存在乘法逆元 假设a∈Zm ...

  9. 公钥密码学中的素数以及对称加密

    密码学,一向被人们认为门槛很高,特别高端...这也是实际,但是这决不意味着普通人无法了解它的精髓,对于喜欢画圆的人来讲,即便是理解了密码技术背后的哪怕一点理论,也是激动人心的. 声明和悲叹 最近,一次 ...

最新文章

  1. GPU微观物理结构框架
  2. P1634 禽兽的传染病
  3. linux命令学习——file
  4. redis学习之常用数据类型
  5. 大名鼎鼎的Requests库用了什么编码风格?
  6. visual studio 的git插件推荐
  7. 平安京服务器维护不能打字,《决战!平安京》:玩的真的累,我真的是服了这破游戏的举报系统...
  8. Make uploadify button text support multiple languages(使uploadify的buttonText支持多国语言)
  9. DCF模型里面的括号计算方法
  10. 暗影精灵4适合计算机专业,暗影精灵4pro怎么样_RTX系显卡带来的不仅是光追-太平洋电脑网...
  11. AWS SQS和Spring JMS集成
  12. WPS for MacOS如何设置自动拼写检查
  13. SNK 推出NEOGEO mini 投币配件,还能当作存钱罐?
  14. Python的初步了解
  15. 详细SpringBoot教程之入门(一)
  16. 《叶圣陶语文教育论集》的阅读笔记和读后感3400字
  17. 使用USB对两个电脑进行串口文件传输
  18. GatewayWorker 与 Workerman的关系
  19. (遇到问题)鼠标右键卡住且一直显示转圈
  20. 复旦微的FMQL10S400ZYNQ芯片的多核操作

热门文章

  1. java 输出_使用IntelliJ IDEA2020.2.2 x64新建java项目并且输出Hello World
  2. 全生命周期管理,是趋势更是未来
  3. 机房冷热通道系统整体解决方案
  4. 案例 | 铅酸蓄电池精细维护
  5. latex参考文献顺序不对_latex模板中,引用多篇参考文献,连续引用压缩问题
  6. -32767转化为二进制_程序员需要了解的硬核知识之二进制
  7. python文本编辑pycharm_PyCharm的基本使用
  8. DL之模型调参:深度学习算法模型优化参数之对LSTM算法进行超参数调优
  9. DL之模型调参:深度学习算法模型优化参数之对深度学习模型的超参数采用网格搜索进行模型调优(建议收藏)
  10. Interview:算法岗位面试—10.10下午—上海某银行算法岗位(偏数据分析,四大行之一)的技术面—关于项目的考察