Andy 胡

导航

RAS算法简单示例(Java版)

RSA算法——由三位发明者Ronald Rivest、Adi Shamir 和 Leonard Adleman 姓氏的首字母拼在一起组成。

RSA算法属于“公开密钥加密技术”,其加密和解密的秘钥不同。

用于加密的密钥可以公开,因此称为“公钥”,而用于解密的密钥是只有自己才知道,称为“私钥”。

简单算法如下所示:

#####创建公钥#####

(1)选两个质数a,b。

    如:a=13,b=29

(2)求c=a*b。

    如:c=377

(3)求d=(a-1)*(b-1)

    如:d=336

(4)选择和d没有公约数的e

    如:e = 5

(5)得到公钥(c,e)

PublicKey [c=377, e=5]

 

#####创建私钥#####

(1)求出f,使其满足(f*e)÷d余1

    如:f=269

(2)得到私钥(c,f)

PrivateKey [c=377, f=269]

 

###使用公钥加密:密文 =((明文的e次方)÷c)的余数

###使用私钥解密:明文 =((密文的f次方)÷c)的余数

 

代码:

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

class PublicKey {
	int c;
	int e;

	@Override
	public String toString() {
		return "PublicKey [c=" + c + ", e=" + e + "]";
	}
}

class PrivateKey {
	int c;
	int f;

	@Override
	public String toString() {
		return "PrivateKey [c=" + c + ", f=" + f + "]";
	}
}

/**
 * 
 * @author Andy Hoo
 *
 */
public class RSA {
	PublicKey publicKey = new PublicKey();
	PrivateKey privateKey = new PrivateKey();

	public void mKey() {
		System.out.println("#####创建公钥#####");
		System.out.println("(1)选两个质数a,b。");
		int a = 13, b = 29;
		System.out.println("	如:a=" + a + ",b=" + b);
		System.out.println("(2)求c=a*b。");
		int c = a * b;
		System.out.println("	如:c=" + c);
		System.out.println("(3)求d=(a-1)*(b-1)");
		int d = (a - 1) * (b - 1);
		System.out.println("	如:d=" + d);
		System.out.println("(4)选择和d没有公约数的e");
		int e;
		for (e = 2; e < d; e++) {
			if (!getCommonDivisor(d, e)) {
				break;
			}
		}
		System.out.println("	如:e = " + e);

		System.out.println("(5)得到公钥(c,e)"); 
		publicKey.c = c;
		publicKey.e = e;
		System.out.println(publicKey);

		System.out.println("#####创建私钥#####");
		System.out.println("(1)求出f,使其满足(f*e)÷d余1");
		int f = 0;
		for (f = 1; f <= d; f++) {
			if ((f * e) % d == 1) {
				System.out.println("	如:f=" + f);
				break;
			}
		}
		System.out.println("(2)得到私钥(c,f)");
		privateKey.c = c;
		privateKey.f = f;
		System.out.println(privateKey);
	}

	/**
	 * 加密
	 * 
	 * @param original原文
	 * @return 密文
	 */
	public int encrypt(int original) {
		System.out.println("###使用公钥加密:密文 =((明文的e次方)÷c)的余数");
		int cryptograph = powAndRemainder(original, publicKey.e, publicKey.c);
		return cryptograph;
	}

	/**
	 * 解密
	 * 
	 * @param cryptograph密文
	 */
	public int decrypt(int cryptograph) {
		System.out.println("###使用私钥解密:明文 =((密文的f次方)÷c)的余数");
		int after = powAndRemainder(cryptograph, privateKey.f, privateKey.c);
		return after;
	}

	/**
	 * 加密解密通用方法: (a的b次方)%c
	 */
	public static int powAndRemainder(int a, int b, int c) {
		BigDecimal bd = new BigDecimal(a);
		// 求幂
		BigDecimal bd2 = bd.pow(b);
		// 取余数
		BigDecimal[] dr = bd2.divideAndRemainder(new BigDecimal(c));
		return dr[1].intValue();
	}

	/**
	 * 求公约数
	 * 
	 * @param a1
	 * @param a2
	 * @return true有公约数/false没有公约数
	 */
	public static boolean getCommonDivisor(int a1, int a2) {
		List<Integer> commonDivisor = new ArrayList<Integer>();
		int min = Math.min(a1, a2);
		for (int n = 2; n <= min; n++) {
			if (a1 % n == 0 && a2 % n == 0) {
				commonDivisor.add(n);
			}
		}
		if (commonDivisor.size() != 0) {
			System.out.println(a1 + "," + a2 + "有公约数" + commonDivisor);
			return true;
		} else {
			System.out.println(a1 + "," + a2 + "没有公约数");
			return false;
		}
	}

	public static void main(String[] args) {
		RSA rsa = new RSA();
		// 获取秘钥
		rsa.mKey();
		// 原文
		int original = 101;
		System.out.println("原文:" + original);
		// 加密
		int cryptograph = rsa.encrypt(original);
		System.out.println("密文:" + cryptograph);
		// 解密
		int after = rsa.decrypt(cryptograph);
		System.out.println("解密后:" + after);
	}
}

  

posted on 2018-10-03 22:29  talkwah  阅读(1123)  评论(0编辑  收藏  举报