RSA 加密及算法实现

来源:互联网 发布:个人信用数据库包含 编辑:程序博客网 时间:2024/06/04 18:52

RSA 加密概述

RSA使用公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。

在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。

RSA广泛应用于计算机网络及通信领域,是目前使用最广泛的加密算法


RSA 加密过程

RSA 加密使用的数学知识

素数

 素数又称质数,指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数整除的数。

互质数

 指两个数中,最大公因子为1的数称为互质数,不是质数也可以构成互质关系。如15和32。

欧拉函数

这里写图片描述

也就是说,a的φ(n)次方被n除的余数为1。或者说,a的φ(n)次方减去1,可以被n整除。比如,3和7互质,而7的欧拉函数φ(7)等于6,所以3的6次方(729)减去1,可以被7整除(728/7=104)。

理解欧拉函数是掌握RSA加密的关键

模反元素

这里写图片描述

加密算法

  1. 随意选择两个大的质数p和q,p不等于q,计算N=p*q。

  2. 根据欧拉函数,求得r = (p-1)(q-1)

  3. 选择一个小于 r 的整数 e,求得 e 关于模 r 的模反元素,命名为d。(模反元素存在,当且仅当e与r互质)

  4. 将 p 和 q 的记录销毁。

算法示例

已知RSA算法中,素数p=5,q=7,模数n=35,公开密钥e=5,密文c=10,求明文。手工完成RSA公开密钥密码体制加密运算。

解:
1. 求出n = p*q = 35;
2. 根据欧拉函数r = (p-1)*(q-1) = 24;
3.题中e = 5,满足e < r ,并且e r 互质.
4.求出d,e*d%t == 1 d为e的模反元素
5. 此时e,d,n均以求出,开始进行加密.
6. 密文c进行反向解密
7. M = c^d%n = 10^5%35 = 5;
8. 明文为5
9. ======用加密进行验算=======
10. m = M^e%n = 10 == c 结果正确

这个例子中,(n,e)为私钥,(n,d)为公钥,可以看出加密用的是公钥,解密用的是私钥。
所以数字签名广泛使用RSA算法

RSA也可以用来为一个消息署名。假如甲想给乙传递一个署名的消息的话,那么她可以为她的消息计算一个散列值(Message digest),然后用她的密钥(private key)加密这个散列值并将这个“署名”加在消息的后面。这个消息只有用她的公钥才能被解密。乙获得这个消息后可以用甲的公钥解密这个散列值,然后将这个数据与他自己为这个消息计算的散列值相比较。假如两者相符的话,那么他就可以知道发信人持有甲的密钥,以及这个消息在传播路径上没有被篡改过。


再来一个示例:

假设p = 3、q = 11(p,q都是素数即可。),则N = pq = 33;

r = (p-1)(q-1) = (3-1)(11-1) = 20;

根据模反元素的计算公式,我们可以得出,e·d ≡ 1 (mod 20),即e·d = 20n+1 (n为正整数);我们假设n=1,则e·d = 21。e、d为正整数,并且e与r互质,则e = 3,d = 7。(两个数交换一下也可以。)

到这里,公钥和密钥已经确定。公钥为(N, e) = (33, 3),密钥为(N, d) = (33, 7)。

编程实现

import java.util.Scanner;public class RSATest {    private static int KeyE; // 公钥    private static int KeyD; // 私钥    private static long MSG;  // 待加密消息    private static int BASE = 3*11; // 基数,两个质数相乘    // 输入格式,请依次输入公钥,私钥和待加密的数据    // 如 7 3 5    public static void main(String[] args) {        Scanner scan = new Scanner(System.in);        KeyE = scan.nextInt();        KeyD = scan.nextInt();        MSG = scan.nextInt();        long encodeMsg = (long) Math.pow(MSG, KeyE)%BASE;        long decodeMsg = (long) (Math.pow(encodeMsg, KeyD)%BASE);        System.out.println("原数据:"+MSG);        System.out.println("加密后数据: "+encodeMsg);        System.out.println("解密加密后的数据: "+decodeMsg);        scan.close();    }}
0 0
原创粉丝点击