\varphi(n)=11
φ(n)=11,则d=4
±
\pm
±k·11。
至此,公钥,私钥便都已经得到。
6、将e、n公开作为公钥进行加密
假设明文为M,密文为C,则加密过程为
M
e
m
o
d
n
=
C
M^e mod n =C
Memodn=C
7、将d,n作为私钥进行解密
C
d
m
o
d
n
=
M
C^d mod n =M
Cdmodn=M
二、RSA算法使用c++语言实现时遇到的问题以及解决方案
1.问题1:模反元素的求解
在第5步中,我们需要计算出e对于
φ
(
n
)
\varphi(n)
φ(n)的模反元素d。
如果使用暴力法求解,那么时间复杂度势必为O(n),这对于一个很大的整数来说,势必需要很长的时间去运行,效率低下,因此需要用一种更快的算法去优化该过程。
解决办法:在第四步中,我们随机产生一个整数e, e的范围是1 < e < φ(n), 并且e与 φ(n) 互质.互质的两个数的最大公约数为1,我们便可以用欧几里得算法去判断是否互质。
欧几里得算法可以用公式表示为gcd(a,b)=gcd(b,a mod b),利用辗转相除的思路。设F(x,y)表示为x,y的最大公约数,取k=x/y,b=x%y,那么x=ky+b,如果一个数能够整除x和y,那么一定可以整除y和b,也就是说,能够整除y和b的数,一定能够整除x和y,所以x和y的公约数和y和b的公约数相同,其最大公约数也相同,则有F(x,y)=F(y,x%y)(x>=y>0),这样就把求两个数的最大公约数转化为求两个更小的数的公约数,直到其中一个数为0,那么另一个数就是两者的最大公约数。
举个例子:
F(42,30)=F(30,12)=F(12,6)=F(6,0)=6
但对于以上过过程,我们如何用代码去实现,我们先从公约数的特点入手。
设x=
k
1
x
1
k_1x_1
k1x1,y=
k
1
y
1
k_1y_1
k1y1,则F(x,y)=
k
1
k_1
k1 F(x1,y1)。
设x=px
1
x_1
x1,(p为素数且y%p!=0)则F(x,y)=F(x1,y)。
现在取p=2。
若x,y均为偶数,则F(x,y)=2F(x/2,y/2)。
若x为偶数,y为奇数则F(x,y)=F(x/2,y)。
若x为奇数,y为偶数则F(x,y)=F(x,y/2)。
若x和y同时为奇数,F(x,y)=F(y,x-y)。(两个奇数相减后必定会出现一个偶数)
这种做法的算法复杂度为O(log2(max(x,y)))。
#include
#include
#include<string.h>
using namespace std;
int isoushu(long x)
{
if(x%20) return 1;
else return 0;
}
int fun(long long a,long long b)
{ if(b>a) return fun(b,a);
else if(a0)return b;
else
{ if(isoushu(a))
if(isoushu(b))
{
return (fun(a>>1,b>>1)<<1);
}
else return fun(a>>1,b);
else
{ if(isoushu(b))
return fun(a,b>>1);
else return (a-b,b);
}
}
}
main()
{
long long a,b;
cin>>a>>b;
cout<<fun(a,b);
}
问题2:大数的幂运算
- 在计算机计算大数的指数的过程中, 计算的数字不断增大, 非常的占用我们的计算资源
- 我们计算的中间过程数字大的恐怖, 我们现有的计算机是没有办法记录这么长的数据的, 会导致溢出.
解决方案:在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快、计算范围更大的算法,产生了快速幂取模算法
从一个最简单的例子入手:求a^b % c = ?
int ans=1;
for(int i=1;i<=b;i++)
{
ans=ans*a;
}
ans=ans%c;
该程序实现存在很大的问题,首先算法时间度为O(n),其次如果a和b过大,很容易就会溢出。
如何进行改进?这里就要用到中学时学到的同余定理:积的取余等于取余的积的取余。
a
b
a^b
ab% c = (a * a * a … a) % c
= ((a % c) * (a % c) * (a % c) … (a % c)) % c
= (a % c)b
^b
b% c
此时我们可以从上述公式中想到既然某个因子取余之后相乘再取余余数保持不变,那么可以通过改良程序得到以下版本。
int ans=1;
a=a%c;//加上这一句
for(int i=1;i<=b;i++)
{
ans=(ans*a)%c;//取余
}
ans=ans%c;
但是这个算法在时间复杂度上没有改进,仍为O(b),不过已经好很多的,但是在c过大的条件下,还是很有可能超时,所以,我们需要用到快速幂算法来进行改进。
关于快速幂的算法的介绍,我么从推导其公式入手。
首先我们将十进制的指数b转换为2进制的形式
其中
a
n
a_n
an代表对应对应第n位的二进制值,非0即1。那么由二进制转换为十进制的公式我们可以得到
化简上述公式可得
则
a
b
a^b
abmod c可重写为
此处的
a
i
a_i
ai要么为0,要么为1,如果
a
i
a_i
ai为0,那么这一项值就为1。所以可以再次将上述式子化简为
其中
k
i
k_i
ki表示
a
i
a_i
ai不为0的项。
同时发现,对于每一项的计算时,计算后一项的结果时用前一项的结果的平方取余。用公式表示为
形如上式的公式推导,我们将其用代码实现。
int ans=1;
a=a%c;
while(b>0)
{
if(b%2==1)
ans=(ans*a)%c;
b=b/2;
a=(a*a)%c;
}
此时,当b=0时,所有的因子都已经相乘,算法结束。于是便可以在O(log b)的时间内完成了。所以在进行模幂运算时, 运算的复杂度已经和指数b的大小没有直接关系了, 有直接关系的是b的二进制bit位数。
问题3:大数的加/减/乘/除/模运算
在RSA算法中的数字极大, 是我们现有计算机无法直接计算的, 所以需要我们手动实现大数的加减乘除. 所以在实现中,直接调用boost库中的大数运算库cppp_int。
boost中的cpp_int库的介绍文档
https://www.boost.org/doc/libs/1_58_0/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html
项目使用的是boost_1_83_0版本的大数库,下载链接https://www.boost.org/users/download/
在VS中还需要将解压好的boost库路径添加到附加目录, 步骤如下
问题4:大数产生随机数
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注网络安全获取)
给大家的福利
零基础入门
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
同时每个成长路线对应的板块都有配套的视频提供:
因篇幅有限,仅展示部分资料
网络安全面试题
绿盟护网行动
还有大家最喜欢的黑客技术
网络安全源码合集+工具包
所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
674985176a4889f7bb130756893764.png)
绿盟护网行动
还有大家最喜欢的黑客技术
网络安全源码合集+工具包
所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-j1gy3b4C-1712545367441)]