RSA是由MIT的三位数学家R.L.Rivest,A.Shamir和L.Adleman[Rivest等1978, 1979]提出的一种用数论构造双钥的方法,被称为MIT体制,后来被广泛称之为RSA体制。其既可以作为加密,又可以用于数字签字。RSA算法的安全性基于数论中大整数分解的困难性。

算法描述

1.独立的选取两个大素数p和q

2.计算\(n = p * q\),其欧拉函数值为\(\phi(n) = (p-1) * (q-1)\)

3.随机选一个整数\(e\),\(1\leq e\leq \phi(n) , gcd(\phi(n),e) = 1\) #gcd为最大公约数

4.在模\(\phi(n)\)下,计算e的逆元\(d = e^{-1} mod \phi(n)\) #意思是\((e * d) mod \phi(n) =1\)

5.以n,e为公钥,密钥为d

加密

将明文分组,每组的数要求小于n(字符串就想办法映射到整数)

计算\(c = m^e mod n\),其中m为明文,c为可以传输的密文

解密

计算\(m = c^d mod n\)

这个过程中只有算法描述中的第三步可能不是直接想到求解方法,对应这个问题,可以用扩展的欧几里得算法来求逆元。

以下算法内容来源自华中科技大学的PPT,在此注明。

问题:求A关于模N的逆元B

迭代计算

N = A × a0 + r0

A = r0 × a1 + r1

r0= r1 × a2 + r2

r1= r2 × a3 + r3

……

rn-2= rn-1 × an + rn

rn-1= rn-2× an+1+ 0

对上面的商数逆向排列(不含余数为0的商)



其中\(b_{-1} = 1\),\(b_0 = a_n\),\(b_i = a_{n-i} * b_{i-1} + b_{i-2}\)

如果商的个数为偶数,则\(b_n\)就是所求的B

如果商的个数为奇数,则\(N-b_n\)就是所求的B

例1:求61关于模105的逆元

105=61×1+44

61 =44×1+17

44 =17×2+10

17 =10×1+7

10 =7 ×1+3

7 =3 ×2+1

3 =3 ×1+0



由于商的个数为偶数(不包括余数为0的商),所以31就是61关于105的逆元

例二:求31关于模105的逆元

105=31×3+12

31 =12×2+7

12 =7 ×1+5

7 =5 ×1+2

5 =2 ×2+1

2 =1 ×2+0



商的个数是奇数,所以105-44 = 61为31关于模105的逆元

代码实现如下:

# coding=utf8
class RSA:
def encrypt(self, string, n, e):
'''
use RSA algorithm to encrypt string
:param string: the String need to be encrypt
:param n: p * q
:param e: encrypt code number
:return: encrypt number
这里是将字符先转换为ASCII值再加密
'''
s = []
for i in string:
s.append(str(ord(i)))
for i in range(len(s)):
s[i] = int(s[i]) ** e % n
return s def decrypt(self, p, q, e, encoding):
'''
:param p: prime number p
:param q: prime number q
:param e: encrypt code number
:param encoding: the string that need to be decrypted
:return: the string that decrypt the encoding number
这里相应的多了一步将ASCII转为字符后拼接的过程
'''
f_n = (p - 1) * (q - 1)
n = p * q
d = RSA.ext_euclid(e, f_n)
s = []
for i in range(len(encoding)):
s.append(chr(encoding[i] ** d % n))
return ''.join(s) @staticmethod
def ext_euclid(e, f_n):
'''
:param e: encrypt code number
:param f_n: p * q
:return: the number that multiply e mod n equals 1
'''
nc = f_n
if e > f_n or type(e) != int or type(f_n) != int:
return -1
quotient = [] #商的列表
remainder = -1 #余数
while remainder != 0:
quotient.append(f_n / e)
remainder = f_n - (f_n / e) * e
f_n = e
e = remainder
quotient = quotient[:-1][::-1] #对应上面写的将商逆序写出来
d_list = [1, quotient[0]]
for i in range(1, len(quotient)):
d_list.append(d_list[-1] * quotient[i] + d_list[-2])
return d_list[-1] if len(quotient) % 2 == 0 else nc - d_list[-1] #如果商的个数是偶数,直接返回bn,否则返回N - bn if __name__ == '__main__':
r = RSA()
p = int(raw_input("p = "))
q = int(raw_input("q = "))
e = int(raw_input("e = "))
string = raw_input("String: ")
en = r.encrypt(string, p * q, e)
print "encrypted code: ", ' '.join(map(str, en))
print "decrypted code: ", r.decrypt(p, q, e, en)

运行如图:



这里可以用小素数的原因是在代码中将明文简单的按字符分组了,但这样会收到频率分析的攻击,在此仅是实验用。

RSA加解密实现的更多相关文章

  1. Rsa加解密Java、C#、php通用代码 密钥转换工具

    之前发了一篇"TripleDes的加解密Java.C#.php通用代码",后面又有项目用到了Rsa加解密,还是在不同系统之间进行交互,Rsa在不同语言的密钥格式不一样,所以过程中主 ...

  2. 【go语言】RSA加解密

    关于go语言的RSA加解密的介绍,这里有一篇文章,已经介绍的很完整了. 对应的go语言的加解密代码,参考git. 因为原文跨语言是跟php,我这里要跟c语言进行交互,所以,这里贴上c语言的例子. 参考 ...

  3. java RSA加解密以及用途

    在公司当前版本的中间件通信框架中,为了防止非授权第三方和到期客户端的连接,我们通过AES和RSA两种方式的加解密策略进行认证.对于非对称RSA加解密,因为其性能耗费较大,一般仅用于认证连接,不会用于每 ...

  4. openssl - rsa加解密例程

    原文链接: http://www.cnblogs.com/cswuyg/p/3187462.html openssl是可以很方便加密解密的库,可以使用它来对需要在网络中传输的数据加密.可以使用非对称加 ...

  5. RSA加解密工具类RSAUtils.java,实现公钥加密私钥解密和私钥解密公钥解密

    package com.geostar.gfstack.cas.util; import org.apache.commons.codec.binary.Base64; import javax.cr ...

  6. PHP RSA加解密详解(附代码)

    前言:RSA加密一般用在涉及到重要数据时所使用的加密算法,比如用户的账户密码传输,订单的相关数据传输等. 加密方式说明:公钥加密,私钥解密.也可以  私钥加密,公钥解密 一.RSA简介 RSA公钥加密 ...

  7. RSA算法原理——(3)RSA加解密过程及公式论证

    上期(RSA简介及基础数论知识)为大家介绍了:互质.欧拉函数.欧拉定理.模反元素 这四个数论的知识点,而这四个知识点是理解RSA加密算法的基石,忘了的同学可以快速的回顾一遍. 一.目前常见加密算法简介 ...

  8. 与非java语言使用RSA加解密遇到的问题:algid parse error, not a sequence

    遇到的问题 在一个与Ruby语言对接的项目中,决定使用RSA算法来作为数据传输的加密与签名算法.但是,在使用Ruby生成后给我的私钥时,却发生了异常:IOException: algid parse ...

  9. JavaScript实现RSA加解密

    在GitHub上找到jsencrypt.js对RSA加解密的工具文件,地址分别是:https://github.com/travist/jsencrypt和https://github.com/ope ...

  10. RSA加解密算法以及密钥格式

    RSA算法: 有个文章关于RSA原理讲的不错: https://blog.csdn.net/dbs1215/article/details/48953589 http://www.ruanyifeng ...

随机推荐

  1. caioj 1236 最近公共祖先 树倍增算法模版 倍增

    [题目链接:http://caioj.cn/problem.php?id=1236][40eebe4d] 代码:(时间复杂度:nlogn) #include <iostream> #inc ...

  2. win10下Python3.6安装、配置以及pip安装包教程

    0.目录 1.前言 2.安装python 3.使用pip下载.安装包 3.1 安装Scrapy 3.2 安装PyQt 3.3 同时安装多个包 3.4 pip的常用命令 1.前言 之前在电脑上安装了py ...

  3. 基本MarkDown语法

    引言 字符串作为一种常见的数据类型,在日常中我们面临各式各样的字符串处理问题,那么,这就要求我们必须掌握一些常用的字符串处理函数.本文尽量囊括常用的字符串处理函数,此文也作为个人的小总结. Pytho ...

  4. windows 终端命令详解

    打开"运行"对话框(Win+R),输入cmd,打开控制台命令窗口... 也可以通过cmd /c 命令 和 cmd /k 命令的方式来直接运行命令 注:/c表示执行完命令后关闭cmd ...

  5. MySQL数据库数据信息迁移

    环境内核信息: [root@zabbix-01 ~]# uname -a Linux lodboyedu-01 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19:2 ...

  6. IntelliJ IDEA(四) :Settings【Appearance and Behavior】

    前言 IDEA是一个智能开发工具,每个开发者的使用习惯不同,如何个性化自己的IDEA?我们可以通过Settings功能来设置.Settings文件是IDEA的配置文件,通过他可以设置主题,项目,插件, ...

  7. Git~GitLab当它是一个CI工具时

    CI我们都知道,它是持续集成的意思,主要可以自动处理包括编译,测试,发布等一系列的过程,而GitLab也同样包含了这些功能,我们可以通过pipeline很容易的实现一个软件从编译,测试,发布的自动化过 ...

  8. SSI学习(二)

    1.SSI指令 #config:指定返回到client浏览器的错误消息.日期和文件大小所使用的格式. #echo:在 HTML 页中插入环境变量的值. #exec:执行一个应用程序或一条 shell ...

  9. TRIZ系列-创新原理-26-复制原理

    复制原理的详细表述例如以下:1)用简化的,廉价的复制品来替代易碎的或不方便操作的物体;    这样能够减少成本,提高可操作性.2)假设已经使用了可见光的复制品,那么使用红外光或者紫外光的复制品:    ...

  10. x86内存映射

    Contents 1 "Low" memory (< 1 MiB) 1.1 Overview 1.2 BIOS Data Area (BDA) 1.3 Extended BI ...