文章目录
素数是除了1与自身无其他因子的数;它们无法被写为数字的乘积;1一般不再考虑之内
例如:2,3,5,7是素数,4,6,8,9不是
素数是数论研究的中心
200以内的素数有:2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199
N的分解就是将N写为其他数字的分解:n=a x b x c
分解一个数要比通过将因子相乘得到一个数要困难得多
素分解:因子都是素数
当两个数最大公约数是1时称两个数互素
相反的,我们可以通过比较它们的素因子的最小阶数得到
最大公约数可以用欧几里得算法得到
ap-1 mod p = 1 ,这里的p为素数且GCD(a,p)=1
36 mod 7 = 1
在公钥加密与素性检验中很有用
对于模n的算术运算
其完全剩余集为:0…n-1
将完全剩余集中与n互素的元素的个数称为欧拉函数Euler Totient Function ø(n)——记住
例:n=10
完全剩余集为{0,1,2,3,4,5,6,7,8,9}
其中与n互素的为{1,3,7,9}
欧拉函数值为4
费尔马定理的推广
若gcd(a,n)=1则对于任意的a,n有 a Φ ( n ) m o d n = 1 a^{\Phi(n)}\mod n=1 aΦ(n)modn=1
举例
1、a=3;n=10; ø(10)=4;
因此34= 81 = 1 mod 10
2、a=2;n=11; ø(11)=10;
1~10都和11互素,一个素数p的欧拉函数值为p-1,费马小定理是欧拉定理的特殊情况
因此210= 1024 = 1 mod 11
经常被用来寻找大素数
传统的方式是试除法:该方法通常用于较小的数字
实际应用中通常利用素数的统计学特征进行选择:
测试所有的素数都满足的特性
但有些合数也同样满足
素数大约是每ln n出现,由于可以忽略偶数所以实际上在n中平均下来看大约寻找一个素数需要的运算量是 0.5 ln n 0.5\ln n 0.5lnn
欧拉定理我们有: a Φ ( n ) m o d n = 1 a^{\Phi(n)}\mod n=1 aΦ(n)modn=1
考虑 a m = 1 ( m o d n ) , GCD ( a , n ) = 1 a^m=1 (\mod n),\text{GCD}(a,n)=1 am=1(modn),GCD(a,n)=1
M是一定存在的(因为可以 m = Φ ( n ) m = \Phi(n) m=Φ(n))
一旦阶数达到m则出现循环
若 m = Φ ( n ) m = \Phi(n) m=Φ(n)那么a被称为本原根
若p为素数则连续不断的a的阶生成了模p的群。

传统的私钥加密使用单一的密钥
发送方与接收方共享密钥
若密钥泄露则通信会出现泄密
是对称的,当事双方地位均等。因此无法避免当接收方伪造消息并声称来源于发送方
对称密钥编码所面临的难题:
密钥分配:通信密钥太多,管理和分发困难。
数字签名和认证。
密码体制上的突破
Diffie & Hellman,“New Direction in Cryptography”,1976。
首次公开提出了“公开密钥密码编码学”的概念。
这是一个与对称密码编码截然不同的方案。
提出公开密钥的理论时,其实用性并没有又得到证明:
当时还未发现满足公开密钥编码理论的算法;
直到1978 年,RSA 算法的提出。
也许是3000年来密码学发展史中最巨大的进步
使用两个密钥-私钥与公钥
非对称,因此参与者地位不再相当
通过巧妙的利用数论观念实现
是私钥密码学的补充而不是取代
为解决两个关键性问题
1️⃣ 密钥分配(key distribution)-如何在不需要密钥分配中心KDC的前提下安全通信
2️⃣ 数字签名-如何验证消息来源于被声称的发送方
公开提出:Whitfield Diffie & Martin Hellman 1976
其实在60年代中期已在NSA中提出
公钥/双密钥/非对称密码学涉及两个密钥
公钥:可被所有人知道,可被用来加密消息与验证签名
私钥:仅被接受者所知,用来解密消息与创建签名。
拿私钥加密就是创建签名
公钥加的密,私钥解开;私钥加的密,公钥解开
该类算法被称为非对称因为:加密消息或验证签名的那一方无法解密消息或创建签名

其主要步骤如下:
1️⃣ 每一用户产生一对密钥,用来加密和解密消息。
2️⃣ 每一用户将其中一个密钥存于公开的寄存器或其他可访问的文件中,该密钥称为公钥,另一密钥是私有的。如图9.1(a)所示,每一用户可以拥有若干其他用户的公钥。
3️⃣ 若Bob要发消息给Alice,则Bob用Alice的公钥对消息加密。
4️⃣ Alice收到消息后,用其私钥对消息解密。由于只有Alice知道其自身的私钥,所以其他的接收者均不能解密出消息。
利用这种方法,通信各方均可访问公钥,而私钥是各通信方在本地产生的,所以不必进行分配。只要用户的私钥受到保护,保持秘密性,那么通信就是安全的。在任何时刻,系统可以改变其私钥,并公布相应的公钥以替代原来的公钥。

在这种方法中,发送方首先用其私钥对消息加密,得到数字签名,然后再用接收方的公钥加密,所得的密文只能被拥有相应私钥的接收方解密,这样可保证消息的保密性,但这种方法的缺点是,在每次通信中要执行四次复杂的公钥算法而不是两次。
Z
=
E
(
P
U
b
,
E
(
P
R
a
,
X
)
)
X
=
D
(
P
U
a
,
D
(
P
R
b
,
Z
)
)
其
中
P
R
为
私
钥
,
P
U
为
公
钥
Z=E(PU_b,E(PR_a,X))\\ X=D(PU_a,D(PR_b,Z))\\ 其中PR为私钥,PU为公钥
Z=E(PUb,E(PRa,X))X=D(PUa,D(PRb,Z))其中PR为私钥,PU为公钥
公钥密码算法依赖于两个密钥,这里:
如果仅知道算法与加密密钥那么要获取解密密钥在计算上是不可行的
当知道相应的加/解密密钥时进行加解密运算在计算上是比较容易的
相关联的两个密钥都可以被用来加密消息而另一个则被用来解密
通常被用在三个范畴
1️⃣ 加密消息(提供安全性)
2️⃣ 数字签名(提供鉴别)
3️⃣ 密钥交换(会话密钥)
像私钥密码算法一样,采用暴力破解理论上是可行的。
密钥非常长(512bit)(目前2048~3072bit)
安全性依赖于足够大的加解密与密码分析之间的难度差异
需要非常大的数字
相比于私钥加密要慢
单向函数:对于一个函数 f ( x ) f(x) f(x),如果对于其定义域上的任意 x, f ( x ) f(x) f(x)都容易计算,同时,对于其值域中几乎所有的取值 y ,计算其逆函数 f − 1 ( y ) f^{-1}(y) f−1(y)都是不可行的,则函数 f ( x ) f(x) f(x)被称为单向函数
可以提供单向函数的三大数学难题
大整数分解问题(简称IFP);
离散对数问题(简称DLP);
椭圆曲线离散对数问题(简称ECDLP)。
单向陷门函数:对于一个单向函数 f ( x ) f(x) f(x),如果其逆函数 f − 1 ( y ) f^{-1}(y) f−1(y)在已知某些辅助信息的情况下容易求解得出,则称该单向函数 f ( x ) f(x) f(x)为单向陷门函数。
构造公钥密码系统的关键是如何在求解某个单向函数的逆函数的NP完全问题中设置合理的“陷门”
一些常用的公钥密码算法
基于因子分解问题的Rabin算法;
椭圆曲线公钥算法;
基于有限域中离散对数难题的ElGamal公钥密码算法
基于代数编码系统的McEliece公钥密码算法;
基于*“子集和”难题的Merkle-Hellman Knapsack**公钥密码算法;*
目前被认为安全的Knapsack型公钥密码算法Chor-Rivest
Rivest, Shamir & Adleman of MIT in 1977
最为人所知与广泛采用的公钥策略
基于整数有限域中模p的指数运算
指数运算需要O((log n)3) (容易)
使用大整数(1024bits)
安全性来源于大整数的分解困难
分解需要 O ( e log n log log n ) O(e^{\log n\log \log n}) O(elognloglogn)(困难)
用户通过如下过程生成密钥对
1️⃣ 选择两个随机的大素数p,q
2️⃣ 计算它们的乘积(系统的模) n = p × q n=p\times q n=p×q
注意欧拉函数值 Φ ( n ) = ( p − 1 ) ( q − 1 ) \Phi(n)=(p-1)(q-1) Φ(n)=(p−1)(q−1)
3️⃣ 随机选取加密密钥e
这里 1 < e < Φ ( n ) , gcd ( e , Φ ( n ) ) = 1 1<e<\Phi(n),\text{gcd}(e,\Phi(n))=1 1<e<Φ(n),gcd(e,Φ(n))=1
4️⃣ 解下面的等式获得解密密钥d
e . d = 1 m o d Φ ( n ) a n d 0 ≤ d ≤ n e.d=1 \mod \Phi(n) \quad and\quad 0≤d≤n e.d=1modΦ(n)and0≤d≤n
5️⃣ 公开其公钥: P U = { e , n } PU=\{e,n\} PU={e,n};保留私钥: P R = { d , n } PR=\{d,n\} PR={d,n}
1️⃣ 加密一条消息M,发送方需要:
获取公钥PU={e,n}
计算C = Me mod n, where 0≤M<n
2️⃣ 解密C,接收方需要
利用私钥PR={d,n}
计算M = Cd mod n
3️⃣ 必要的时候需要进行分块

1️⃣ p = 17 & q = 11 p=17\ \&\ q=11 p=17 & q=11
2️⃣ n = p q = 17 × 11 = 187 n = pq =17\times 11=187 n=pq=17×11=187
3️⃣ Φ ( n ) = ( p – 1 ) ( q − 1 ) = 16 × 10 = 160 \Phi(n)=(p–1)(q-1)=16 \times 10=160 Φ(n)=(p–1)(q−1)=16×10=160
4️⃣ e : gcd ( e , 160 ) = 1 ; e = 7 e: \text{gcd}(e,160)=1; e=7 e:gcd(e,160)=1;e=7
5️⃣ d : d ⋅ e = 1 m o d 160 a n d d < 160 V a l u e i s d = 23 s i n c e 23 × 7 = 161 = 1 × 160 + 1 d: d\cdot e=1 \mod 160 \ and \ d < 160\ Value\ is\ d=23 \ since\ 23\times7=161= 1\times160+1 d:d⋅e=1mod160 and d<160 Value is d=23 since 23×7=161=1×160+1
6️⃣ P U = { 7 , 187 } PU=\{7,187\} PU={7,187}
7️⃣ P R = { 23 , 187 } PR=\{23,187\} PR={23,187}
加密解密过程如下:
选取M=88(88<187)
加密: C = 8 8 7 m o d 187 = 11 C=88^7\mod 187=11 C=887mod187=11
解密: M = 1 1 23 m o d 187 = 88 M=11^{23}\mod 187=88 M=1123mod187=88

数学的破解有三种:
分解n,从而获得ø(n) 然后是 d
直接确定ø(n) ,然后是d
直接d
目前大家觉得1024-2048bit是安全的。
第一个提出的公钥类策略
Diffie&Hellman
是一个使用的公开交换密钥的方法
在大量的商业应用中使用
该算法的有效性是建立在计算离散对数很困难的基础上
共享的参数:
大素数 q或多项式
一个 mod q的本原根a:即a mod q,a2 mod q,… ,aq-1 mod q各不相同
在这种方法中,素数q和本原根α是两个公开的整数,假定用户A和B希望交换密钥,那么用户A选择一个随机整数 X A < q X_A<q XA<q,并计算 Y A = α X A m o d q Y_A=\alpha ^{X_A}\mod q YA=αXAmodq,类似的,用户B也随机选择一个随机整数 X B < q X_B<q XB<q,并计算 Y B = α X B m o d q Y_B=\alpha ^{X_B}\mod q YB=αXBmodq
A和B保持其X是私有的,但是对另一方而言Y是公开访问的,即 X A 和 X B X_A和X_B XA和XB是私有的, Y A 和 Y B Y_A和Y_B YA和YB是公开的。
用户A计算 K = ( Y B ) X A m o d q K=(Y_B)^{X_A}\mod q K=(YB)XAmodq并将其作为密钥;用户B计算 K = ( Y A ) X B m o d q K=(Y_A)^{X_B}\mod q K=(YA)XBmodq并将其作为密钥,这两种计算所得的结果相同。
至此双方完成了密钥的交换。通常这个秘密值被用于对称密码的密钥。现在考虑一个敌手能够观察到密钥交换的全过程并且期望得到这个秘密K。由于XA和XB是私有的,所以攻击者只能通过q,α,YA,YB来进行攻击,这样,他就必须求离散对数才能确定密钥。例如,要对用户B的密钥进行攻击,攻击者就必须先计算
X
B
=
d
log
α
,
q
(
Y
B
)
X_B=d\log_{\alpha,q}(Y_B)
XB=dlogα,q(YB)
然后他就可以像用户B那样计算出密钥K。
K
=
(
Y
A
)
X
B
m
o
d
q
K=(Y_A)^{X_B}\mod q
K=(YA)XBmodq
计算过程如下:

Diffie-Hellman密钥交换的安全性建立在下述事实之上:求关于素数的模素数幂运算相对容易,而计算离散对数却非常困难:对于大素数,求离散对数被认为是不可行的。
Alice 和 Bob 希望交换密钥:
1️⃣ 共享 q=353 与 α=3
2️⃣ 选择密钥:
A 选择XA=97, B 选择XB=233
3️⃣ 计算公钥:
YA=397 mod 353 = 40 (Alice)
YB=3233 mod 353 = 248 (Bob)
4️⃣ 会话密钥:
K
A
B
=
(
Y
B
)
X
A
m
o
d
353
=
24
8
97
m
o
d
353
=
160
A
l
i
c
e
计
算
得
到
K
A
B
=
(
Y
A
)
X
B
m
o
d
353
=
4
0
233
m
o
d
353
=
160
B
o
b
计
算
得
到
K_{AB}=(Y_B)^{X_A}\mod 353=248^{97}\mod 353=160 \quad Alice计算得到\\ K_{AB}=(Y_A)^{X_B}\mod 353=40^{233}\mod 353=160 \quad Bob计算得到\\
KAB=(YB)XAmod353=24897mod353=160Alice计算得到KAB=(YA)XBmod353=40233mod353=160Bob计算得到
与Diffie-Hellman一样,ElGamal的系统用户也是共同选择一个素数q,α是q的素根。
🔑 用户A生成的密钥对如下:
1️⃣ 随机生成整数XA使得1<XA<q-1。
2️⃣ 计算 Y A = α X A m o d q Y_A=\alpha ^{X_A}\mod q YA=αXAmodq
3️⃣ A的私钥为 X A X_A XA,公开密钥为 { q , α , Y A } \{q,\alpha,Y_A\} {q,α,YA}。
🔑 其他任何用户B通过A的公开密钥可以加密信息:
1️⃣ 将信息表示为一个整数M,其中1≤M≤q-1,以分组密码序列的方式来发送信息,其
中每个分块的长度不小于整数q。
2️⃣ 选择任意整数k,使得1≤k≤q-1。
3️⃣ 计算一次密钥 K = ( Y A ) k mod q K=(Y_A)^k\ \text{mod}\ q K=(YA)k mod q。
4️⃣ 将M加密成明文对 ( C 1 , C 2 ) (C_1,C_2) (C1,C2),其中
C 1 = α k mod q ; C 2 = K M mod q C_1=\alpha ^k\ \text{mod}\ q;C_2=KM\ \text{mod}\ q C1=αk mod q;C2=KM mod q
🔑 用户A恢复明文:
1️⃣ 通过计算 K = ( C 1 ) X A mod q K=(C_1)^{X_A}\ \text{mod}\ q K=(C1)XA mod q恢复密钥。
2️⃣ 计算 M = ( C 2 K − 1 ) mod q M=(C_2K^{-1})\ \text{mod}\ q M=(C2K−1) mod q。
可用下一个图进行说明:


若信息需要分组加密后发出则要求每个分组必须使用唯一的 k k k,否则对手可用一个已知的分组M1计算其他
优点:
密钥尺度较小;
参数选择较灵活;
具有由数学难题保证的安全性;
实现速度较快。
[1] 西安交通大学计算机网络安全与管理2022年春PPT 田暄
[2] 密码编码学与网络安全(第七版),William Stallings著,王后珍等译
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个.pfx格式的证书,我需要使用ruby提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o
我在加密来self正在使用的第三方供应商的值时遇到问题。他们的指令如下:1)Converttheencryptionpasswordtoabytearray.2)Convertthevaluetobeencryptedtoabytearray.3)Theentirelengthofthearrayisinsertedasthefirstfourbytesontothefrontofthefirstblockoftheresultantbytearraybeforeencryption.4)EncryptthevalueusingAESwith:1.256-bitkeysize,2.25
给定一个nxmbool数组:[[true,true,false],[false,true,true],[false,true,true]]有什么简单的方法可以返回“该列中有多少个true?”结果应该是[1,3,2] 最佳答案 使用转置得到一个数组,其中每个子数组代表一列,然后将每一列映射到其中的true数:arr.transpose.map{|subarr|subarr.count(true)}这是一个带有inject的版本,应该在1.8.6上运行,没有任何依赖:arr.transpose.map{|subarr|subarr.in
给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at