📄 rsaalgo.java
字号:
/******************************************************
*COPYRIGHT@author YIMINGHE , 创建日期 : 2005-12-11
*
* @FUDAN UNIVERSITY
*
*Email : yiming_water@hotmail.com,0234075@fudan.edu.cn
*
*MSN : yiming_water@hotmail.com
*
*TODO
******************************************************/
package algo;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.StringTokenizer;
import tool.BinaryInteger;
/**
* rsa加密算法 注意: 1:rsa的位数一定要比加密的数据位数大??!! 2:对中文支持不太好,原因不明,会出现乱码
*
* @author YiMingHe
*
*/
public class RsaAlgo {
/**
* p1,p2为随机的两个大素数 n1=p1*p2,为公匙 fn1=(p1-1)*(p2-1) d1为随机选取满足(d1,fn1)=1,为密匙
* e1满足 e1*d1 mod fn1= 1 ,为公匙 plaintext为密文 ciphertext为明文
*/
private BinaryInteger prime1 = null, prime2 = null, n1 = null, fn1 = null,
d1 = null, e1 = null, plaintext = null, ciphertext = null;
private int bitlength = 512 / 2;
private int block = 512;
// 加密
public static final int ENCRYPT = 1;
// 解密
public static final int DECRYPT = 2;
// 随机数
private final static SecureRandom random = new SecureRandom();
/**
* 构造函数,得到指定位数的密匙
*
* @param bits,所需素数的位数
*/
public RsaAlgo(int bits) {
this.bitlength = bits/2;
setCipher();
}
/**
* 专为加密解密构造,rsa
*
* @param n
* @param ed
* @param type,
*/
public RsaAlgo(String n, String ed, int type) {
n1 = new BinaryInteger(n, 10);
if (type == RsaAlgo.ENCRYPT) {
e1 = new BinaryInteger(ed, 10);
} else if (type == RsaAlgo.DECRYPT) {
d1 = new BinaryInteger(ed, 10);
}
}
/**
* 产生公匙密匙
*
*/
private void setCipher() {
prime1 = BinaryInteger.probablePrime(bitlength, random);
prime2 = BinaryInteger.probablePrime(bitlength, random);
// 产生公匙n1
n1 = prime1.multiply(prime2);
fn1 = (prime1.subtract(BinaryInteger.ONE)).multiply(prime2
.subtract(BinaryInteger.ONE));
// 产生密匙
while (true) {
d1 = new BinaryInteger(bitlength, random);
// d1 = BinaryInteger.probablePrime(bitlength, random);
// if (fn1.gcd(d1).intValue() ==
// 1&&d1.compareTo(n1)==-1&&d1.compareTo(prime1.max(prime2))!=-1)
if (fn1.gcd(d1).intValue() == 1)
break;
}
// 产生公匙e1
e1 = d1.modInverse(fn1);
}
/**
* 得到公匙
*
* @return,第一个为n1,第二个为e1
*/
public BinaryInteger[] getPublicCiphers() {
BinaryInteger[] publiciphers = new BinaryInteger[2];
publiciphers[0] = n1;
publiciphers[1] = e1;
return publiciphers;
}
/**
* 得到密匙
*
* @return d1,密匙
*/
public BinaryInteger getPrivateCipher() {
return d1;
}
/**
* 用于加密时设置
*
* @param n
* @param e
*/
public void setEncryptCiphers(String n, String e) {
n1 = new BinaryInteger(n, 10);
e1 = new BinaryInteger(e, 10);
}
/**
* 用于解密是设置
*
* @param n
* @param d
*/
public void setDecryptCiphers(String n, String d) {
n1 = new BinaryInteger(n, 10);
d1 = new BinaryInteger(d, 10);
}
/**
*
* @param plain,名文
* @param n1,公匙
* @param e1,公匙
* @return,加密后的byte数组
*/
public String encrypt(String bplain) {
// if (bitlength < bplain.length()*2*8)
// throw new Exception("注意:rsa的位数一定要比加密的数据位数大??!!");
BinaryInteger plain = new BinaryInteger(bplain.getBytes());
return new String(plain.modPow(e1, n1).toString(10));
}
/**
*
* @param ciphertext,密文
* @param n1,公匙
* @param d1,密匙
* @return,返回解密后的byte[]数组
*/
public String decrypt(String sciphertext) {
BinaryInteger ciphertext = new BinaryInteger(sciphertext, 10);
return new String(ciphertext.modPow(d1, n1).toByteArray());
}
/**
* 大量文本的分段加密
*
* @param s
* ,大量明文
* @return ,加密后密文,密文端之间以空格隔开
*/
public String largeEncrypt(String s) {
int strsize = block / 8 / 4;
String result = "";
for (int i = 0; i < s.length(); i += strsize) {
String part = "";
if (i + strsize < s.length())
part = s.substring(i, i + strsize);
else
part = s.substring(i);
result += encrypt(part) + "\n";
}
return result;
}
/**
* 密文的分段解密
*
* @param s
* ,以空格隔开的密文端
* @return,明文
*/
public String largeDecrypt(String s) {
StringTokenizer token = new StringTokenizer(s);
String result = "";
while (token.hasMoreTokens()) {
result += decrypt(token.nextToken());
}
return result;
}
/**
* byte[] c=c1+c2
*
* @param c1
* @param c2
* @return
*/
public static byte[] connect(byte[] c1, byte[] c2) {
byte[] c = new byte[c1.length + c2.length];
int index = 0;
for (int i = 0; i < c1.length; i++)
c[index++] = c1[i];
for (int i = 0; i < c2.length; i++)
c[index++] = c2[i];
return c;
}
public static void main(String[] argv) {
// !rsa的位数一定要比加密数据的位数大!!??
String test = "134568796中国1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf1354sdfsadf";
ArrayList store = new ArrayList();
// rsa的位数
int block = 512;
// 每16个unicode字符加密一次
int strsize = block / 8 / 4;
RsaAlgo rsa = new RsaAlgo(block);
/*
* for(int i=0;i<test.length();i+=strsize) { String part="";
* if(i+strsize<test.length()) part=test.substring(i,i+strsize); else
* part=test.substring(i); String re=rsa.encrypt(part); store.add(re); }
*
* for(int i=0;i<store.size();i++)
* System.out.println((String)store.get(i));
*
* for(int i=0;i<store.size();i++) {
* System.out.print(rsa.decrypt((String)store.get(i))); }
*/
String e = rsa.largeEncrypt(test);
System.out.println(e);
System.out.println(rsa.largeDecrypt(e));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -