RSA加密算法简单介绍

注:本篇文章只是本人在学完RSA加密之后的个人总结,若有不正确的地方,欢迎指正OVO

RSA是一种公钥加密算法,它具有公钥和私钥两种密钥:公钥用来加密,并且是公开的,私钥是用来解密的,是不公开的,也不需要和数据一起传送,这样就能防止密钥在网络传输时泄露。

RSA算法设计的原理是依靠着模幂运算,例如加密、解密以及密钥的产生。

1.密钥设计

首先,我们需要了解密钥设计的思想:
①加密计算:c = m^e mod n;
②解密计算:m = c^d mod n;
其中m为明文, c为密文,e为公钥,d为私钥,n为一个我们要产生的大数。

所以,根据以上两个式子有:
dk( ek(m) ) = m
= (m^e mod n) ^d mod n        # 这里也就是先加密再解密
= m^(ed) mod n
那么要实现解密生成的数据和明文一样,**m^(e
d) mod n一定要等于m。①**

m^φ(n) mod n = 1 → m ^(tφ(n)) mod n = 1 → m ^(tφ(n)+1) mod n = m ②
∴① ②中两个式子相对应,即有:ed = (t*φ(n)+1) → ed = 1 mod φ(n)
不难看出,公钥e和私钥d是关于φ(n)互逆的。

到这里,可能会有疑问,为什么别人不能根据公钥e和 φ(n)来直接求得私钥呢?,这就是接下来要讲的:如何生成n使别人难以计算φ(n)。

2.大数n的生成

首先,我们需要知道一个定理:若n = p*q, 且p,q为素数,那么φ(n) =φ(p) * φ(q) = (p-1) * (q-1)
而且我们知道,想要分解一个大的数是非常困难的,所以我们需要找两个大数p,q,来使生成的n难以被分解计算,而且我们需要p,q都是素数,才能满足上述定理,所以我们问题就变成了如何产生大素数p,q。

3.产生大素数p,q

我们思路可以是这样:要产生大素数,我们可以先用随机数产生一个大数,然后再判断其是否为素数就行。
产生大数简单,random库可以实现,那么如何验证其是否为素数呢?这里我们不能使用简单的素数判别法:如遍历比它小的所有数,并且对其取余,看是否为0。因为这样只适用于小数,对于大数来说,计算时间太长了,根本行不通。所以这里我们需要采用一种素数检测法:Miller-Rabin算法

Miller-Rabin算法思想
首先,由费马小定理:a^p-1 = 1 mod p (p为素数),我们可以将p-1写成2 ^k*m形式,其中,a我们可随机生成,但需满足1<=a<=n-1。
那么a ^p-1 = ((a ^m) ^2) ^2 … ,所以我们可以先验算a ^m mod p的结果是否为±1,
若是,那么a ^p-1 = ((a ^m) ^2) ^2 … 一定为1,那么可以判断出p为素数;
若不是,令b=a^ m mod p的结果,然后依次计算b, b^ 2,b^ 4,…,b^ 2^(k-1) mod n,若发现有一个为±1,则p是素数,否则,p为合数。

但是,这种算法并不是100%正确,有时候也会将合数当成素数输出,所以一般情况下,我们可以产生伪随机数来进行素数检测,而不是使用随机数来检测。

Miller-Rabin算法具体代码如下:

#判断是否为素数(Miller-Rabbin),RoundTime表示循环测试的次数,提高准确率
def _MillerRabin(self, num: int, times: int):# Miller-Rabin素性检验# return False if n is not primem = num-1k = 0while m & 1 == 0:m >>= 1k += 1for _ in range(times):x = random.randrange(2, num)x = self._FastExpMod(x, m, num)for _ in range(k):y = (x*x) % numif y == 1 and x != 1 and x != num-1:return Falsex = yif y != 1:return Falsereturn True

4.密钥生成

我们生成两个大素数p,q后,我们就可以直接得到φ(n)。对于公钥e,我们可以随机生成,但需要满足gcd(e,φ(n))=1(可以使用欧几里得除法来判断余数是否为1)。

然后对于私钥d,因为ed = 1 mod φ(n)所以我们只需要求逆元就能得到d,然而求逆元可以根据欧几里得除法逆过程来求得。欧几里得除法求逆代码如下:

 #求x,y为两个所求逆元,其中y为私钥def _ExtendedEuclidean(self, a: int, b: int):# 扩展欧几里得算法# return x, y, gcd(a,b)# 使得x*a + y*b = gcd(a,b)# 非递归实现if b == 0:return 1, 0, ay = s1 = 1x = s2 = 0q, r = divmod(a, b)while r:m = xn = yx = s1 - x*qy = s2 - y*qs1 = ms2 = na = bb = rq, r = divmod(a, b)return x, y, b

5.加解密

加解密过程我们只需根据:
①加密计算:c = m^e mod n;
②解密计算:m = c^d mod n; 来计算就行。

但是,对于大数的计算,我们不能直接使用高级语言所给定的计算来求,这样也会导致时间太长,我们在这需要使用平方-乘算法来求。该算法具体代码如下:

#平方乘算法求余数 base^n mod mod
def _FastExpMod(self, base: int, exp: int, mod: int):# 快速幂取模: 蒙哥马利幂模运算# return base**exp % modbase = base % modexp = exp % modpower = 1while exp:if exp & 1:power = (power * base) % modexp >>= 1base = (base * base) % modreturn power

全部代码

import randomclass RSA:def __init__(self):self._lowPrimes = [2, 3, 5, 7, 11, 13, 17, 19]for i in range(self._lowPrimes[-1]+1, 1000):for p in self._lowPrimes:if i % p:continueelse:breakelse:self._lowPrimes.append(i)def _FastExpMod(self, base: int, exp: int, mod: int):# 快速幂取模: 蒙哥马利幂模运算# return base**exp % mod# base = base % mod# exp = exp % modpower = 1while exp:if exp & 1:power = (power * base) % modexp >>= 1base = (base * base) % modreturn powerdef _MillerRabin(self, num: int, times: int):# Miller-Rabin素性检验# return False if n is not primem = num-1k = 0while m & 1 == 0:m >>= 1k += 1for _ in range(times):x = random.randrange(2, num)x = self._FastExpMod(x, m, num)for _ in range(k):y = (x*x) % numif y == 1 and x != 1 and x != num-1:return Falsex = yif y != 1:return Falsereturn Truedef _IsNotPrime(self, num: int, times: int = 10):# 分解质因数测试 + Miller-Rabin素性检验# return True if n is not primeif num < 2:return True# 分解质因数for p in self._lowPrimes:d, m = divmod(num, p)if m == 0:if d == 1:return Falseelse:return True# Miller-RabinisP = self._MillerRabin(num, times)return not isPdef _FindPrime(self, low_bits: int, high_bits: int) -> int:# 在区间[2^lowBits,2^highBits)寻找一个素数lowNum = 1 << low_bitshighNum = 1 << high_bitsn = random.randrange(lowNum, highNum)while self._IsNotPrime(n):n = random.randrange(lowNum, highNum)return ndef _ExtendedEuclidean(self, a: int, b: int):# 扩展欧几里得算法# return x, y, gcd(a,b)# 使得x*a + y*b = gcd(a,b)# 非递归实现if b == 0:return 1, 0, ay = s1 = 1x = s2 = 0q, r = divmod(a, b)while r:m = xn = yx = s1 - x*qy = s2 - y*qs1 = ms2 = na = bb = rq, r = divmod(a, b)return x, y, bdef hex2int(self, x: str) -> int:# hex字符串转换为整数return int(x, 16)def int2hex(self, x: int) -> str:# 整数转换为hex字符串return hex(x)[2:]def hex2bin(self, x: str) -> str:# hex字符串转换为字节数组if len(x) & 1:x = "0" + xbuffer = bytearray()for i in range(0, len(x), 2):buffer.append(self.hex2int(x[i:i+2]))x = bytes(buffer)return x.decode()def RSA_Key_Gen(self):# 生成RSA密钥对key_len = 1024p = self._FindPrime(key_len-6, key_len-2)q = self._FindPrime(key_len+2, key_len+6)n = p * qphi = (p-1)*(q-1)gcd = 0while gcd != 1:e = random.randint(1, 2**100)_, d, gcd = self._ExtendedEuclidean(phi, e)  # 欧几里得求逆元if d < 0:d += phiwith open("RSA_Public_Key.txt", 'w') as f:res = str(n)+"\n"+str(e)f.write(res)with open("RSA_Secret_Key.txt", 'w') as f:res = str(n)+"\n"+str(d)f.write(res)def Encrypt(self, plain_text: str, public_key: tuple) -> int:data = int(plain_text.encode().hex(), 16)  # 明文进行处理n, e = public_key  # 获得公钥result = self._FastExpMod(data, e, n)return resultdef Decrypt(self, secret_text: int, secret_key: tuple) -> str:n, d = secret_keyresult = self._FastExpMod(secret_text, d, n)return self.hex2bin(self.int2hex(result))

RSA加密算法简单介绍以及python实现相关推荐

  1. python网站设计理念_简单介绍下python Django框架的历史,设计理念及优势_Django讲解2...

    简单介绍下python Django框架的历史,设计理念及优势 Django是一个高层次的 Python Web 框架,它是一个鼓励快速开发和干净,实用的框架设计.Django可以更容易地快速构建更好 ...

  2. RSA加密算法简单分析

    预备知识 1)RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名.RSA以它的三个发明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命 ...

  3. 代理IP的背后原理简单介绍与python写一个获取代理IP的爬虫

    title: 代理IP的那些事 copyright: true top: 0 date: 2019-11-13 14:20:39 tags: 代理IP categories: 爬虫笔记 permali ...

  4. 简单介绍一下python的魔方方法

    .构造和析构:魔法方法总是被下划线包围例如_init_,其"魔力"体现于总能够在适当的时候被自动调用. (1)init__构造函数:初始化或实例化变量 (2)new(cls[,-] ...

  5. 简单介绍python装饰器

    这篇文章简单介绍一下python装饰器,希望对你们有所帮助. 简单正常python例子: def up(text):return text.upper() #转成大写 def lo(text):ret ...

  6. Python, CPython, Pypy, Jython的简单介绍

    简单地说,Python是一门编程语言,任何一种编程语言都需要用另一种语言来实现它,比如C语言就是用机器语言来实现的.所以,Python根据实现方式不同分为了CPyhton.Pypy.Jython等. ...

  7. 蒙哥马利大数模乘与RSA加密算法简介

    在网上看了一圈蒙哥马利模乘相关的博客,没有看到讲得比较清晰的,趁最近闲下来自己写一篇. 首选明确三个问题: 1.蒙哥马利模乘是什么? 蒙哥马利模乘是一种数学家蒙哥马利(Montgomery)提出的一种 ...

  8. 快速指数算法 (RSA的简单实现)

    1.RSA算法简单介绍 2.快速指数算法 在RSA中,加.解密过程都是要求某个整数的整数次幂后再取模.大多时候,这两个整数都会比较大,这时候直接按含义来进行计算时得到的中间结果会超出计算机所允许的整数 ...

  9. rsa加密算法python_模拟新浪微博登录(Python+RSA加密算法)

    声明: 由于本人使用用的是Python语言,以下内容就在该语言下进行解释说明.有使用Java语言的可以参考IT男杂记(http://marspring.mobi/http-client-weibo/) ...

最新文章

  1. 大年初五,Python、Go、C...你最爱用哪种语言?
  2. c语言超级经典400道题目,C语言超级经典400道题目.doc
  3. 【设计模式】备忘录模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )
  4. 山西计算机等级考试科目一模拟试题,2011山西省计算机等级考试试题 二级ACCESS一点通科目一...
  5. NOI.AC-序列【堆】
  6. 这四种攻击单片机的主要技术你了解多少?
  7. python作品阐述_Python网络编程基础的作品鉴赏-
  8. 微信JSAPI支付,报错当前页面的URL未注册
  9. 领域应用 | 智能导购?你只看到了阿里知识图谱冰山一角
  10. 中html倒入css那么套路,CSS常用套路
  11. 爬取博主所有文章并保存到本地(.txt版)--python3.6
  12. python带参数的装饰器的作用_Python带参数的装饰器运行原理解析
  13. Wavesequencer Hyperion for Mac(数字模块化合成器)
  14. ADBAppium常见问题梳理
  15. 第九章 CSS-DOM
  16. 使用Pyecharts进行全国水质TDS地图可视化全过程8:绘制中国地图,使用timeline把多个值放在一个地图上
  17. Android 11 PackageManagerService源码分析(一):PMS启动的总体流程
  18. 安卓手机m3u8转为mp4格式100%有效的方法
  19. 不常用SQL语句整理
  20. 计算机考试成绩有疑惑,计算机考研疑惑 真的好难受

热门文章

  1. 北京有哪些驻京办餐厅的菜比较好吃?
  2. C++创建型模式-原型模式
  3. 基于Python深度图生成3D点云
  4. 2022赛季RoboMaster 空中机器人六轴无人机云台程序框架代码开源
  5. python培训 杭州6
  6. Vue生命周期(vue.js学习笔记)
  7. Git/Bitbucket Workflow
  8. 二次不等式恒成立求参数范围
  9. HTML实操-音乐播放器
  10. Maatwebsite/excel的简单使用