RSA加密算法

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Test{
	
	/**
	 * 需要加密的字符串
	 */
//	public final static String STRING = "Hello world!";
	public final static String STRING = "Hello world! It is a beautiful day.";
//	public final static String STRING = "Hello world! It is a beautiful day. Hello world! It is a beautiful day. Hello world! It is a beautiful day.";
	
	public static void main(String[] args){
		
		System.out.println("============1.寻找质数=========");
		int[] primeNum = getPQE();
		System.out.println("p="+primeNum[0]+", q="+primeNum[1]+", e="+primeNum[2]);
		
		
		System.out.println("============2.生成密钥=========");
		KeyPair key = getKeyPair(primeNum[0], primeNum[1], primeNum[2]);
		System.out.println(key);
		
		
		System.out.println("============3.加密============");
		ArrayList<Long> list = encryToList(STRING, key);
		String s = encryToString(STRING, key);
		System.out.println("加密后的文本是:");
		System.out.println(s);
		
		
		System.out.println("============4.解密============");
		System.out.println("解密之后的文本是:");
		System.out.println(decry(list, key));
		
	}
	
	
	/**
	 * 4.解密加密后的值的list
	 * @param list
	 * @param key
	 * @return
	 */
	static String decry(ArrayList<Long> list, KeyPair key){
		
		StringBuilder sb = new StringBuilder();
		List<Long> delist = new ArrayList<Long>();
		for (long ch : list) {
			BigInteger a = BigInteger.valueOf(ch).pow(key.getD());
			BigInteger b = a.mod(BigInteger.valueOf(key.getN()));
			delist.add(b.longValue());
			
			sb.append((char)b.longValue());
			
//			System.out.println((char)ch+" "+ch+"\t"+b+" "+(char)b.longValue());
		}
		
		return new String(sb);
	}
	
	
	
	/**
	 * 3.加密成String形式
	 * @param string
	 * @param key
	 * @return
	 */
	static String encryToString(String string, KeyPair key){
		
		StringBuilder sb = new StringBuilder();
		
		byte[] str = string.getBytes();
		
		for (long ch : str) {
			
			BigInteger a = BigInteger.valueOf(ch).pow(key.getE());
			BigInteger b = a.mod(BigInteger.valueOf(key.getN()));
			
			sb.append((char)b.longValue());
			
//			System.out.println((char)ch+" "+ch+"\t"+b+" "+(char)b.longValue());
		}
		
		return new String(sb);
	}
	/**
	 * 3.加密成list形式
	 * @param string
	 * @param key
	 * @return
	 */
	static ArrayList<Long> encryToList(String string, KeyPair key){
		
		byte[] str = string.getBytes();
		
		ArrayList<Long> list = new ArrayList<Long>();
		
		for (long ch : str) {
			
			BigInteger a = BigInteger.valueOf(ch).pow(key.getE());
			BigInteger b = a.mod(BigInteger.valueOf(key.getN()));
			list.add(b.longValue());
			
//			System.out.println((char)ch+" "+ch+"\t"+b+" "+(char)b.longValue());
		}
		
		return list;
		
	}
	
	
	
	/**
	 * 2.生成密钥
	 * @param p
	 * @param q
	 * @param e
	 * @return
	 */
	static KeyPair getKeyPair(long p, long q, long e){
		KeyPair key = new KeyPair();
		
		long n = p*q;
		long euler = (p-1)*(q-1); // e必须与euler互质,1<e<euler
		// 计算满足下式的数 d
		long d = 0L;
		for(long i=1; ; i++){
//			System.out.println("-- 正在寻找公钥 "+i+" --");
			if(e*i%euler == 1){
				d = i;
				break;
			}
		}
		
		key.setE((int)e);
		key.setD((int)d);
		key.setN((int)n);
		
		return key;
	}
	
	
	/**
	 * 1.寻找三个质数
	 * @return
	 */
	static int[] getPQE(){
		List<Integer> numList = new ArrayList<Integer>();
		for(int i=101; i<500; i++){
			if(isPrime((long)i)){
				numList.add(i);
//				System.out.println("----- "+i+" -----");
			}
		}
		Random random = new Random();
		int p = 0;
		int q = 0;
		int e = 0;
		
		p = numList.get(random.nextInt(numList.size()));
		do {
			q = numList.get(random.nextInt(numList.size()));
		} while (p==q);
		do {
			e = numList.get(random.nextInt(numList.size()));
		} while (e==p || e==q);
		
		return new int[]{p,q,e};
	}
	
	
	/**
	 * 0.判断一个数是否质数
	 * @param num
	 * @return
	 */
	static boolean isPrime(long num){
		if(num<=0) return false;
		for(int i=2; i<num; i++){
			if(num%i==0){
				return false;
			}
		}
		return true;
	}
	
	
		
}


// 密钥
class KeyPair {
	
	private int e;
	private int d;
	private int n;

	public void setE(int e) {
		this.e = e;
	}

	public int getE() {
		return e;
	}

	public void setD(int d) {
		this.d = d;
	}

	public int getD() {
		return d;
	}

	public void setN(int n) {
		this.n = n;
	}

	public int getN() {
		return n;
	}

	public int[] getPublicKey(){ 
		return new int[]{e,n};
	}
	public String getPublicKeyStr(){ 
		return "公钥:("+e+","+n+")";
	}
	
	public int[] getPrivateKey(){ 
		return new int[]{d,n};
	}
	public String getPrivateKeyStr(){ 
		return "私钥:("+d+","+n+")";
	}
	
	public String toString() {
		return ("KeyPair["+getPublicKeyStr()+","+getPrivateKeyStr()+"]");
	}
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏菩提树下的杨过

利用java8对设计模式的重构

java8中提供的很多新特性可以用来重构传统设计模式中的写法,下面是一些示例: 一、策略模式 ? 上图是策略模式的类图,假设我们现在要保存订单,OrderSer...

35412
来自专栏追不上乌龟的兔子

使用Python标准库functools中的lru_cache实现缓存

很简单,也很容易理解,但是不难发现这个函数在计算斐波那契数列的时候事实上进行了很多重复计算,例如:

1404
来自专栏武培轩的专栏

设计模式-观察者模式

模式定义 定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。主题(Subject)是被观察的对象,而其所有依赖者(Obse...

2613
来自专栏架构师之旅

【Java SE】Java NIO系列教程(十二)Java NIO与IO

当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异...

1825
来自专栏calmound

知识点提纲

操作系统: 1. 进程的有哪几种状态,状态转换图,及导致转换的事件。 2. 进程与线程的区别。 3. 进程通信的几种方式。 4. 线程同步几种方式。(一定要会写...

3378
来自专栏人工智能LeadAI

ElasticSearch优化系列三:索引过程

大家可能会遇到索引数据比较慢的过程。其实明白索引的原理就可以有针对性的进行优化。ES索引的过程到相对Lucene的索引过程多了分布式数据的扩展,而这ES主要是用...

3529
来自专栏知识分享

1-关于单片机通信数据传输(中断发送,大小端,IEEE754浮点型格式,共用体,空闲中断,环形队列)

写这篇文章的目的呢,如题目所言,我承认自己是一个程序猿.....应该说很多很多学单片机的对于...先不说别的了,,无论是学51的还是32的,,,先问一下大家用串...

2395
来自专栏码匠的流水账

分布式id生成方案概述

对于每个标识,都需要有一个命名空间(namespace),来保证其相对唯一性。 分布式的ID生成,以Twitter Snowflake为代表的, Flake 系...

272
来自专栏架构师之路

1分钟实现“延迟消息”功能

一、缘起 很多时候,业务有“在一段时间之后,完成一个工作任务”的需求。 例如:滴滴打车订单完成后,如果用户一直不评价,48小时后会将自动评价为5星。 一般来说怎...

4456
来自专栏鹅厂优文

深入浅出Lua虚拟机

本文标题是”深入浅出 Lua 虚拟机”,其实重点在浅出这两字上。毕竟作者的技术水平有限。但是听说名字要起的屌一点文章才有人看,故而得名。

75712

扫描关注云+社区