java 实现RSA 算法

RSA算法的实现原理

RSA公钥密码体制描述如下:(m为明文,c为密文)

  1. 选取两个大素数p,q。p和q保密
  2. 计算n=pq,r=(p-1)(q-1)。n公开,r保密
  3. 随机选取正整数1<e<r,满足gcd(e,r)=1.e是公开的加密密钥
  4. 计算d,满足de=1(mod r).d是保密的解密密钥
  5. 加密变换:  c=m^e mod n
  6. 解密变换:  m=c^d mod n

所以在实现RSA算法之前,首先要先做以下几件事:

  • 实现素数的选择判断,以便于随机生成素数
  • 实现模逆运算,以便求出某个元的逆元,因为ed互逆
  • 实现快速模指运算
  • 根据以上公式,实现RSA的加密与解密

实现素数的选择判断

检验素数的方法有很多,最简单的一个方法就是平方根检验,还有费马检测,素数的概率性检测算法等等。或者直接进行循环判断。详细的不多说,大家有兴趣的可以自行前去百度,这里说下费马检测的,具体请看代码:

/**
	 * 费马测试
	 * @param args
	 */
	public static boolean isPrimeByFeima(int n) {
		boolean result=false;
		int test = n/2;
		Random random = new Random();
		
		
		List<Integer>lists = new ArrayList<Integer>();
		
		for(int i=0;i<test;i++) {
			int j = random.nextInt(n);
			int mod = 1;
			for(int k=0;k<n;k++) {
				mod = j%n *mod;
				if(mod > n) {
					mod = mod %n;
				}
			}
			
			if(mod == j) {
				lists.add(j);
			}
		}
		
		if(lists.size() ==test) {
			result = true;
			System.out.println("该数是素数!");
		}else {
			result=false;
			System.out.println("该数不是素数!");
		}
		return result;
	}

我们可以获取一个随机数,然后用以上方法判断这个数是否是素数,是的话就返回,不是的话就继续生成。以此来生成两个随机素数。当然在,笔者具体代码里用的是更为难得一点方法,有兴趣的可以去看看,当然也可以用以上方法去生成素数。

模逆运算

这是用来求一个数的逆元,如果说ab=1,则我们可以说ab互逆,当然,这不是简单的直接让a= 1/b,而是应该用扩展欧几里得算法,去求得一个元的逆元,模逆则是 ab=1modn 好了用java如何实现呢?下面请看一段代码:

// 求逆元
	public static int Inverse(int a, int b) { //返回的结果为moda后b的逆元
//		System.out.println("a="+a);
//		System.out.println("b="+b);
		int[] m = { 1, 0, a };
		int[] n = { 0, 1, b };
		int[] temp = new int[3];
		int q = 0; // 初始化
		boolean flag = true;
		while (flag) {
			q = m[2] / n[2];
			for (int i = 0; i < 3; i++) {
				temp[i] = m[i] - q * n[i];
				m[i] = n[i];
				n[i] = temp[i];
			}
			if (n[2] == 1) {
				if (n[1] < 0) {
					n[1] = n[1] + a;
				}
				return n[1];
			}
			if (n[2] == 0) {
				flag = false;
			}
		}
		return 0;
	}

用这个方法,可以求出一个元的逆元,当然,百度上还可以百度到其他方法,大家可以自行尝试。这里只给出一个最简单的方式

快速模指运算

模指运算就比较简单,但是大家要注意一点,不要直接把这个指乘出来再运算,而应该mod一个,乘一个。

//幂指运算
   public static int calc2(int a,int b,int mod){
   	int result =1;
   	for(int i = 0;i<b;i++){
   		result = (i%mod) *result;
   		if(result > mod){
   			result = result%mod;
   		}
   		
   	}
   	return result;
   }

RSA加密

之后便是根据公式,进行加密操作就可以了。一步一步进行操作

/**
 * Rsa 的加密算法
 * @param M
 * @return
 */
	public  int c_RSA(){
		RSAUtil rsaUtil= new RSAUtil();
		ModUtils modUtils = new ModUtils();
		p = RSAUtil.getPrime();
		q = RSAUtil.getPrime();
		while(p==q){
			q = RSAUtil.getPrime();
		}
		int n = (p-1)*(q-1);
		Random rd = new Random();
		e = rd.nextInt(n);
		
		C= (int) modUtils.calc(M, e, p*q);
		d = ModUtils.Inverse(n,e);
		if(d==0){
			return c_RSA();
		}
		
		return C;
	}

在这个方法里面,求取d的时候有可能会导致d==0,这里存在一点小bug,不过概率很小,笔者测试过了100次大概会出现3次,所以为了以防万一,最后再做个判断,若是d=0,那么这组ed就舍弃。

结果

除此之外,笔者还做了一个 图形界面,方便大家操作。下面展示下操作结果

输入13进行加密
在这里插入图片描述
加密结果如下:

将这个密文进行解密
在这里插入图片描述

RSA的java简单实现代码下载地址

  • 2
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值