文章目录

  • RSA数学原理
    • 获取两个不相等的质数pq
    • 把p和q相乘,得到n
    • 计算出小于n的自然数中,有多少数与n互质(欧拉函数)
    • 在1和φ(n)之间,选取一个随机质数e
    • 求e和φ(n)的模反元素d(裴蜀定理、扩展欧几里得算法)
    • 把n和e封装成公钥,n和d封装成私钥
    • 实例
    • RSA参数的选择
    • 代码

RSA数学原理

获取两个不相等的质数pq

质数又称素数,在自然数中,除了1和自身外,不能被其他自然数整除。比如10以内的质数有:1,2,3,5,7。

把p和q相乘,得到n

比如:n=61*53=3233,用二进制表示为:110010100001。

我们常说的RSA算法中的多少位,就是n用二进制表示后的位数,在我们例子就是12位。目前商用中一般都是2048位。

计算出小于n的自然数中,有多少数与n互质(欧拉函数)

如果两个数的最大公约数为1,那么我们说这两个数互质,记:GCD(a,b)=1。其中GCD表示两个数的最大公约数。

使用欧拉函数来判断是否互质:

  • 情况1:如果n=1,那么与n互质的自然数只有1
    φ(n)=1φ(n)=1 φ(n)=1

  • 情况2:如果n是质数,那么与n互质的自然数有n-1个,
    φ(n)=n−1φ(n)=n-1 φ(n)=n−1
    例:φ(7)=6例:φ(7)=6

  • 情况3:如果n可以因式分解为两个互质数的乘积,则:
    φ(n)=φ(p)×φ(q)=(p−1)×(q−1)例:φ(56)=φ(7)∗φ(8)=6∗7=42φ(n)=φ(p)\times φ(q)=(p-1)\times (q-1) \\ 例:φ(56)=φ(7)*φ(8) = 6 * 7 = 42 φ(n)=φ(p)×φ(q)=(p−1)×(q−1)例:φ(56)=φ(7)∗φ(8)=6∗7=42

  • 情况4:如果n可以写成某个数的质数次幂(其中k为质数),则:
    φ(n)=φ(pk)=pk−pk−1=pk(1−1p)例:φ(49)=φ(72)=72−71=42φ(n)=φ(p^k)=p^k-p^{k-1}=p^k(1-\frac 1p) \\ 例:φ(49)=φ(7^2)=7^2 - 7^1 = 42 φ(n)=φ(pk)=pk−pk−1=pk(1−p1​)例:φ(49)=φ(72)=72−71=42

  • 情况5:根据以上规律,总结出一个通用的公式:

n=p1k1×p2k2…prkr注:任意一个整数,都可以写成两个质数的乘积\qquad n=p_1^{k^1} \times p_2^{k^2} \ldots p_r^{k^r} \quad 注:任意一个整数,都可以写成两个质数的乘积n=p1k1​×p2k2​…prkr​注:任意一个整数,都可以写成两个质数的乘积
⇓\qquad \Downarrow⇓
φ(n)=φ(p1k1)×φ(p2k2)…φ(prkr)\qquad φ(n)=φ(p_1^{k^1}) \times φ(p_2^{k^2})\ldots φ(p_r^{k^r})φ(n)=φ(p1k1​)×φ(p2k2​)…φ(prkr​)
⇓\qquad \Downarrow⇓
φ(n)=p1k1(1−1p1)×p2k2(1−1p2)…prkr(1−1pr)\qquad φ(n)= p_1^{k^1}(1- \frac 1p_1) \times p_2^{k^2}(1- \frac 1p_2) \ldots p_r^{k^r}(1- \frac 1p_r)φ(n)=p1k1​(1−p1​1​)×p2k2​(1−p1​2​)…prkr​(1−p1​r​)
⇓\qquad \Downarrow⇓
φ(n)=p1k1×p2k2…prkr×(1−1p1)×(1−1p2)…(1−1pn)\qquad φ(n)=p_1^{k^1} \times p_2^{k^2}\ldots p_r^{k^r}\times (1- \frac 1p_1)\times(1- \frac 1p_2)\ldots(1- \frac 1p_n)φ(n)=p1k1​×p2k2​…prkr​×(1−p1​1​)×(1−p1​2​)…(1−p1​n​)
⇓\qquad \Downarrow⇓
φ(n)=n×(1−1p1)×(1−1p2)…(1−1pn)\qquad φ(n)=n\times(1- \frac 1p_1)\times(1- \frac 1p_2)\ldots(1- \frac 1p_n)φ(n)=n×(1−p1​1​)×(1−p1​2​)…(1−p1​n​)

  • 总结:通过欧拉函数最后的通式,我们发现最后的结果只和n和p有关,和p的幂无关,这点很重要,在我们用程序实现时,能够大大的简化我们的逻辑代码。

回到算法中,我们需要计算与n互质的个数,也就是求φ(n),根据欧拉函数,计算过程如下:
φ(n)=φ(3233)=φ(61)×φ(53)=60×52=3120φ(n)=φ(3233)=φ(61)×φ(53)=60×52=3120 φ(n)=φ(3233)=φ(61)×φ(53)=60×52=3120

在1和φ(n)之间,选取一个随机质数e

即在1~3120中选取e=17。

求e和φ(n)的模反元素d(裴蜀定理、扩展欧几里得算法)

模反元素也称为模倒数,可以写成 a−1≡b(modn)a^{−1}≡b \ (mod \ n)a−1≡b (mod n) 或 ab≡1(modn)ab≡1 \ (mod \ n)ab≡1 (mod n)。(ab和1关于n同模)

如果两个正整数a和n互质,那么一定可以找到整数b,使得a*b与n相除,余数为1,记作:(a×b)%n=1⇒(a×b)−1n=1(a \times b) \% n = 1 \Rightarrow \frac {(a \times b) - 1} n = 1(a×b)%n=1⇒n(a×b)−1​=1。

例:求3和11的模反元素
(3×b)−111=1=>b=4\frac {(3 \times b) - 1} {11} =1 => b = 4 11(3×b)−1​=1=>b=4

  • 通过上面的运算,我们可以算出一些简单数的模反元素,对于较大的数来说,我们需要引入新的计算工具:裴蜀定理,通过它,我们可以通过一个二元一次方程来得出模反元素。在求模反元素时,给予二个整数a、b,必存在整数x、y使得ax + by = gcd(a,b),而我们真正要获取的是x的值。
  • 定义:如果a与b互质,即GCD(a, b) = 1,二元一次方程ax+by=1ax + by = 1ax+by=1有一对正整数解,其中x即为a、b的模反元素。同理,上面的例子我们可以化简成这样:3x + 11y = 1
  • 疑惑:对于二元一次方程,好像不可解(也可以说有无穷多个解),我们之前都是解方程组。即然定理已经解决,两个互素(质)数组成的二元一次方程有一对整数解,那肯定是能解,解法我们需要引入另一个数学工具:扩展欧几里得算法

扩展欧几里得算法这个算法其实就是上面我们求最大公约数时,用到的辗转相除法+它的逆运算,我们看个例子就明白是什么意思了

例1:求47x+30y=147x + 30y = 147x+30y=1的解

解:使用辗转相除法,我们可以得到:
47=30×1+1730=17×1+1317=13×1+413=4×3+14=1×4+047 = 30 \times 1 + 17 \ \\ 30 = 17 \times 1 + 13 \ \\ 17 = 13 \times 1 + 4 \ \ \ \\ 13 = 4 \times 3 + 1 \ \ \ \ \ \\ 4 = 1 \times 4 + 0 \ \ \ \ \ \ 47=30×1+17 30=17×1+13 17=13×1+4   13=4×3+1     4=1×4+0      
我们可以得到GCD(47, 30) = 1,对到处第二行,我们移项处理:
1=13−4×34=17−13×113=30−17×117=47−30×11 = 13 - 4 \times 3 \\ 4 = 17 - 13 \times 1 \\ 13 = 30 - 17 \times 1 \\ 17 = 47 - 30 \times 1 \\ 1=13−4×34=17−13×113=30−17×117=47−30×1
我们把第二行代入第一行中:
1=13−(17−13×1)⏞4×3⇓1=4×13−3×17⇓1=4×(30−17)⏞13−3×s17⇓…1=(−7)×47+11×30解得:x=−7(即为我们要求的模反元素d)y=111 = 13 - \overbrace{(17 - 13 \times 1)}^4 \times 3 \\ \Downarrow \\ 1 = 4 \times 13 - 3 \times 17 \\ \Downarrow \\ 1 = 4 \times \overbrace{(30 - 17)}^{13} - 3 \times s17 \\ \Downarrow \\ \ldots \\ 1 = (-7) \times 47 + 11 \times 30 \\ 解得:x=-7(即为我们要求的模反元素d) \quad y = 11 1=13−(17−13×1)​4​×3⇓1=4×13−3×17⇓1=4×(30−17)​13​−3×s17⇓…1=(−7)×47+11×30解得:x=−7(即为我们要求的模反元素d)y=11
回到算法中,我们根据e=17和φ(n)=3120,得到一个二元一次方程:17x+3120y=117x + 3120y = 117x+3120y=1,再根据扩展欧几里得算法,我们可以得到方程的解:x=2753即:d=2753x = 2753 \quad 即:d = 2753x=2753即:d=2753。

把n和e封装成公钥,n和d封装成私钥

  • 公钥:(3233,17)(3233, 17)(3233,17)
  • 私钥:(3233,2753)(3233, 2753)(3233,2753)

实例

私钥和公钥获取:

  1. 取p=47, q=71;

  2. 则n = p * q = 3337, Φ(n)=(p-1)(q-1)=3220;

  3. 随机选择加密密钥e,e与Φ(n)互素,取e=79;

  4. 79 * d=1(mod n) =》 d = 1019101^91019;

  5. 公钥为(3337,79),私钥为(3379,1019)

假设要加密的明文是m=6882326879666683:

  • 首先,根据n的大小将m进行分组,这里我们把明文m分成六个组,即:m1=688, m2=232, m3=687, m4=966, m5=668, m6=003;
  • 接着分别对各个分组进行加密运算,第一个分组加密为c1=68879688^{79}68879(mod 3337) = 1570,类似的,对其余各个分组分别进行加密运算,得到如下密文:c=1570 2756 2091 2276 2423 158;
  • 解密时用私钥1019分别对明文进行解密运算,即:m1=157010191570^{1019}15701019(mod 3337) = 688,对其余的密文用同样的计算方法就可以把密文恢复出来,即得到密文。

RSA参数的选择

p和q的选择:

  • p和q要足够大

  • p和q应为强素数。如p满足以下三个条件,即为强素数:

    (1)P-1有大素数因子r

    (2)P+1有大素数因子s

    (3)R-1有大素数因子t

  • p和q的差不能太小

  • p-1和q-1的最大公因数应很小

公钥e的选择:e不能太小;最好选择e为modΦ(n)的阶数,意思就是要使i的值尽量大才能使得ei≡ (mod Φ(n))成立。i等于(p-1)(q-1)/2是最好的。一般建议取e=2162^{16}216+1=65537

代码

(1)质数判断

import Gcd from './Gcd'
/*** 质数类*/
class Prime {private static pNumArr: Array<number> = []/*** 判断一个数是否为质数* @param num 转入值*/public static isPrimeNum(num: number): boolean {// 1和2都是质数if (num < 3) {return true}// i取开方,效率要比/2高出许多for (let i = 2; i <= Math.sqrt(num); i++) {if (num % i === 0) {return false}}return true}/*** 1. 任意两个质数构成互质关系,比如13和61。2. 一个数是质数,另一个数只要不是前者的倍数,两者就构成互质关系,比如3和10。3. 如果两个数之中,较大的那个数是质数,则两者构成互质关系,比如97和57。4. 1和任意一个自然数是都是互质关系,比如1和99。5. p是大于1的整数,则p和p-1构成互质关系,比如57和56。6. p是大于1的奇数,则p和p-2构成互质关系,比如17和15。*/public static coprime(n1: number, n2: number): boolean {// 保证n1比n2要大if (n2 > n1) {let tmp = n1n1 = n2n2 = tmp}// 两个数中, 有一个是1, 则两数互质if (n1 === 1 || n2 === 1) {return true}// 如果两数相邻, 则两数互质if (n1 - n2 === 1) {return true}// 如果大数为奇数, 则n1-n2 = 2, 则两数互质if (n1 % 2 === 1 && n1 - n2 === 2) {return true}// 如果较大的数为质数, 则两数互质if (this.isPrimeNum(n1)) {return true}// 有一个是质数, 别一个不为此数的倍数, 则两数互质if ((this.isPrimeNum(n1) || this.isPrimeNum(n2)) && n1 % n2 !== 0) {return true}// 如果两个数都为质数, 则两个数互质if (this.isPrimeNum(n1) && this.isPrimeNum(n2)) {return true}// 如果两个数的最大公约数为1, 则两个数互质if (Gcd.gcd(n1, n2) === 1) {return true}return false}/*** 获取该数下所有的质数* @param num 转入的数*/public static getAllPrimeNum(num: number) {let arr = []for (let i = 1; i <= num; i++) {if (this.isPrimeNum(i)) {arr.push(i)}}return arr}/*** 把一个正整数分解为两个质数的乘积* @param num*/public static break(num: number) {this.getBreakArr(num)return this.pNumArr}/*** 把一个正整数分解为两个质数的乘积(中间步骤)* @param num*/private static getBreakArr(num: number) {// 获取该数/2的所有质数let arr = this.getAllPrimeNum(Math.floor(num / 2))// 能被这个数整除的最大质数let maxNum = 1for (let i = 0; i < arr.length; i++) {if (num % arr[i] === 0) {maxNum = arr[i]}}// 除数let divNum = num / maxNumif (maxNum !== 1) {this.pNumArr.push(maxNum)return this.break(divNum)} else {this.pNumArr.push(divNum)return maxNum}}
}export default Prime

(2)欧拉函数计算

import Prime from './Prime'
import Util from './Util'
/*** 欧拉函数*/
class Euler {/*** 根据欧拉函数取与此数互质的个数* @param num 参数*/public static getEulerNum(num: number) {Prime.break(num)let arr = Util.uniqueArr(Prime.break(num))let result = numfor (let i = 0; i < arr.length; i++) {result *= 1 - 1 / arr[i]}return Math.floor(result)}
}export default Euler

(3)最大公约数计算-欧几里得算法-辗转相除法

/*** 最大公约数*/
class Gcd {/*** 计算2个数的最大公约数* @param n1 数1* @param n2 数2*/public static gcd(n1: number, n2: number): number {let s = Math.floor(n1 / n2)let y = n1 % n2// console.log(n1 + ' = ' + n2 + '*' + s + ' + ' + y)if (y === 0) {return n2} else {return this.gcd(n2, y)}}/*** 扩展欧几里德算法 - 求方程的解 (详细注释版)* 我们要求:47x + 30y = 1的解,下面为辗转相除法的步骤:* 47 = 30*1 + 17* 30 = 17*1 + 13* 17 = 13*1 + 4* 13 = 4*3 + 1*** @param num1 数1* @param num2 数2*/public static gcdEx(n1: number, n2: number): Array<number> {// 两数相除的商let q = Math.floor(n1 / n2)// 两数相除的余数let r = n1 % n2// 当到 13 = 4*3 + 1 即4 % 1 = 0时 返回// 返回值为:1 | -4 即:x=1 y=-4if (n2 % r === 0) {// 转化为:1 = 13 + 4*(-3)// 所以返回:x=1 y=q*(-1)=-3return [1, q * -1]} else {let ret = this.gcdEx(n2, r)// x和y为上一步返回的值let x = ret[0]let y = ret[1]// x1和y1为当前步骤的值let x1 = 1let y1 = -q// console.log('----', x, y, x1, y1)// x2和y2为当前步骤计算得到的值// 1 = 13 + 4*(-3)// 4 = 17 + 13*(-1)// 代入得:1 = 13 + (17 + 13*(-1)) * (-3)// 计算得:1 = 17*(-3) + 13*4 ==> x=-3 | y=4let x2 = y * x1let y2 = y * y1 + xret = [x2, y2]return ret}}
}
export default Gcd

(4)裴蜀定理的求解-扩展欧几里得算法

/*** 最大公约数*/
class Gcd {/*** 计算2个数的最大公约数* @param n1 数1* @param n2 数2*/public static gcd(n1: number, n2: number): number {let s = Math.floor(n1 / n2)let y = n1 % n2// console.log(n1 + ' = ' + n2 + '*' + s + ' + ' + y)if (y === 0) {return n2} else {return this.gcd(n2, y)}}/*** 扩展欧几里德算法 - 求方程的解 (详细注释版)* 我们要求:47x + 30y = 1的解,下面为辗转相除法的步骤:* 47 = 30*1 + 17* 30 = 17*1 + 13* 17 = 13*1 + 4* 13 = 4*3 + 1*** @param num1 数1* @param num2 数2*/public static gcdEx(n1: number, n2: number): Array<number> {// 两数相除的商let q = Math.floor(n1 / n2)// 两数相除的余数let r = n1 % n2// 当到 13 = 4*3 + 1 即4 % 1 = 0时 返回// 返回值为:1 | -4 即:x=1 y=-4if (n2 % r === 0) {// 转化为:1 = 13 + 4*(-3)// 所以返回:x=1 y=q*(-1)=-3return [1, q * -1]} else {let ret = this.gcdEx(n2, r)// x和y为上一步返回的值let x = ret[0]let y = ret[1]// x1和y1为当前步骤的值let x1 = 1let y1 = -q// console.log('----', x, y, x1, y1)// x2和y2为当前步骤计算得到的值// 1 = 13 + 4*(-3)// 4 = 17 + 13*(-1)// 代入得:1 = 13 + (17 + 13*(-1)) * (-3)// 计算得:1 = 17*(-3) + 13*4 ==> x=-3 | y=4let x2 = y * x1let y2 = y * y1 + xret = [x2, y2]return ret}}
}
export default Gcd

RSA加密算法的数学原理相关推荐

  1. RSA加密算法破解及原理

    " RSA加密算法是一种非对称加密算法,目前被广泛应用.本文介绍RSA算法的基本原理和破解方法." RSA在互联网上被广泛应用,典型的如各个网站的证书. 很多应用数据的加密也是使用 ...

  2. 【数据结构与算法】之深入解析RSA加密算法的实现原理

    一.密码学历史 密码学的历史大致可以追溯到两千年前,相传古罗马名将凯撒大帝为了防止敌方截狱情报,用密码传送情报.凯撒的做法很简单,就是对二十几个罗马字母建立一张对应表,这样,如果不知道密码本,即使截获 ...

  3. [杂记]对RSA算法的数学原理的一点思考

    转载于:https://www.cnblogs.com/CQBZOIer-zyy/p/9808041.html

  4. RSA背后的数学原理

    2019独角兽企业重金招聘Python工程师标准>>> 由于本文档无法添加"<sup>e</sup>"标签来书写公式,直接把原文链接过来了 ...

  5. RSA加密算法原理及RES签名算法简介(转载)

    第一部分:RSA算法原理与加密解密 一.RSA加密过程简述 A和B进行加密通信时,B首先要生成一对密钥.一个是公钥,给A,B自己持有私钥.A使用B的公钥加密要加密发送的内容,然后B在通过自己的私钥解密 ...

  6. android支付宝rsa加密算法,支付宝支付流程与RSA算法原理

    RSA加密算法的原理 支付宝的三种支付流程 1.所有的支付逻辑处理,全在服务器完成,现在被淘汰了 原理就是电商App吧所有的信息提交给电商服务器,然后又电商服务器与支付宝服务器进行交互 2.所有的支付 ...

  7. RSA加密算法,从实际应用到基础原理(一)

    RSA加密算法,从实际应用到基础原理(二)https://blog.csdn.net/mashiqing/article/details/127042988 日常的基础应用,登录远程服务器 在使用ss ...

  8. RSA 加密算法原理简述

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

  9. RSA加密算法原理及其Java实现

    RSA加密算法原理及其Java实现 RSA加密算法的基本原理 主要步骤 解密过程证明 java实现 简单介绍了RSA加密算法的原理及其Java实现:原文过长时,进行了分段加密. RSA加密算法的基本原 ...

最新文章

  1. Python数据清理之解析XLRD文件
  2. 使用registerForActivityResult替代onActivityResult
  3. 研究表明:安卓和iOS应用无节操滥用邮箱和定位数据
  4. CCTYPE函数系列
  5. Confluence 6 升级完成后的检查
  6. linux磁盘同步函数,Linux系统调用fsync函数详解
  7. Reporting Service 在文本框中换行的问题
  8. 发球机器轰灭了中国姑娘的奇迹
  9. svn 1.6 linux 下载,LINUX下Subversion1.6.17 部署
  10. 申通快递:1月快递服务业务收入25.65亿元 同比增长21.27%
  11. 你给我这么多报表,让我如何是好
  12. Node:正则验证手机号和身份证号
  13. leetcode笔记:Validate Binary Search Tree
  14. 第六章 jQuery选择器
  15. java4.25生成车牌号_泸牌16年涨882倍 超25万人拍一张车牌为哪般?
  16. 记录一次C#爬虫记录,获取必应图片
  17. 可靠性测试项目之可靠性试验
  18. 第14章 LINQ to SOL
  19. RBP as a streaming server(一)
  20. JMM(Java Memory Model)

热门文章

  1. Xshell显示找不到匹配的outgoing encryption算法怎么解决
  2. css文字图片动画_文字图像互动动画
  3. onTouchEvent / MotionEvent(轨迹球事件、触摸屏事件、键盘事件)
  4. Defects4J 安装与使用
  5. C#委托和事件 EventHandle和EventArgs
  6. Photoshop给草坪上的人物加上唯美的紫色霞光
  7. app运行中的crash崩溃异常日志收集
  8. 威洛特:狗狗骨折如何应急的去处理?
  9. Python二分搜索算法
  10. SQLzoo 习题记录06-The JOIN operation Quiz