武汉大学应用密码学RSA加密解密大作业

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1 对RSA算法的理解

RSA加密算法是一种非对称加密算法,它基于一个非常简单的数论思想:“将两个素数乘起来是很容易的,但是分解该乘积是非常困难的”。

1.1加解密步骤

(1)生成公钥和私钥

a)随机生成两个不相等的大素数p和q,计算N=p*q;

b)根据欧拉函数,求出φ=(p-1)*(q-1);

c)选择一个小于r的整数e,求e关于r的模反元素d使得e*d mod φ

=1

得到公钥,私钥

(2)加密

给定明文m,公钥,计算密文c = m e(N)。

(3)解密

给定密文c,私钥,计算明文m’ = c d(N)。

1.2素性检验

RSA算法的实现难点之一是生成大素数,这就需要生成一个大数并对其进行素性检验。素性检验有很多种方法。其中包括确定性方法和随机方法。确定性方法有试除法(埃拉托斯特尼筛法),卢卡斯-莱默检验法和AKS素数测试。常见的随机方法有费马素性检验,米勒-拉宾检验和欧拉-雅科比测试。本次作业采用就是米勒-拉宾检验方法。

米勒-拉宾(Miller Rabin) 算法原理:

要测试N 是否为素数,首先将N-1 分解为2s d。在每次测试开始时,先随机选一个介于[1, N-1]的整数a,之后如果对所有的r∈[0, s-1],若a d mod N ≠ 1 且a2^rd mod N ≠1,则N 是合数。否则,N 有3/4 的概率为素数。

1.3安全问题

(1)公共模数攻击。每个人具有相同的r,但有不同的指数e和d,这是不安全的。

(2)低加密指数攻击。如果选择了较低的e值,虽然可以加快计算速度,但存在不安全性。

(3)低解密指数攻击。如果选择了较低的d值,也是不安全的。

(4)选择密文攻击。如A想让T对一个T不愿意签名的消息m’签名,A首先选择一个任意值x,计算y=x e(mod r),然后要求T对m=ym’签名,A最后计算(m d mod r)x-1 mod r =( ym’) d x-1mod r= m’d mod r。

还有一些不是直接对RSA的算法本身进行的攻击,如中间人攻击、时间攻击、边信道攻击等。

2.具体实现

2.1函数说明

void ProducePrime(JTextField prime):使用JA V A的Biginteger生成512位的

大数,再用Miller Robin算法检验是否是素数。参数prime即为生成的大素数。

boolean MillerRobin(BigInteger n):用Miller Robin检验判断大数n是否是素数。

BigInteger modex(BigInteger a, BigInteger b, BigInteger n):模幂运算,计算a b mod n

BigInteger inverse(BigInteger a, BigInteger b):求逆运算,计算a-1 ( b )

String Encode(String Plaintext, BigInteger n, int nLen, int m, JTextField e):加密,用公钥(n,e)对明文Plaintext加密。

String Decode(String Ciphertext, BigInteger n, int m, JTextField d):解密,用私钥d对密文Ciphertext解密。

2.2JA V A代码

import java.math.BigInteger;

import java.util.Random;

import java.util.Scanner;

import javax.swing.JTextField;

public class RSA {

public static void main(String[] args) {

String s;

JTextField p = new JTextField(35);

JTextField q = new JTextField(35);

JTextField e = new JTextField(35);

JTextField d = new JTextField(35);

ProducePrime(p);

ProducePrime(q);

BigInteger pp = new BigInteger(p.getText());

BigInteger qq = new BigInteger(q.getText());

BigInteger oo = (pp.subtract(new BigInteger("1"))).multiply(qq

.subtract(new BigInteger("1")));

BigInteger ee;

do {

ee = new BigInteger(100, new Random()).mod(oo);

} while (MillerRobin(ee) == false);

e.setText(ee.toString());

d.setText(inverse(ee, oo).toString());

BigInteger n = pp.multiply(qq);

int nLen = n.bitLength();

int m = (int) (Math.ceil((double) (nLen) / 16.0));

nLen = (nLen - 1) / 16;

String Ciphertext = new String();

相关文档
最新文档