RSA
也是公开密钥密码,非对称密码
要破解面临两大问题
- 大整数分解(integer factorization)——由2个质数p,q相乘得到大整数n容易,由n分解为2个质数难(耗时)
- 离散对数(discrete logarithm)——m的e次方模上n得到c容易;已知c,n,e得到m难
上面的情况都是针对较大的数
原理
java实现
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Scanner;
public class RSA_scanner {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
HashMap<String, Object> map = getKeys();
RSAPublicKey publicKey = (RSAPublicKey) map.get("public");//公钥
RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private");//私钥
String plaintext = new String(); //明文
String ciphertest = new String(); //密文
while(scanner.hasNext()) {
if("-e".equals(scanner.nextLine())){
//读取明文
plaintext = ReadText2String(new File("src/test2/plaintext.txt"));
System.out.println("读入的明文是:\n" + plaintext);
try {
ciphertest = encryptByPublicKey(plaintext, publicKey);
} catch (Exception e) {
e.printStackTrace();
}
//将密文写入文件
WriteText2String(ciphertest, new File("src/test2/ciphertext.txt"));
System.out.println("加密后的密文是:\n" + ciphertest);
}
if("-d".equals(scanner.nextLine())){
//读取密文
ciphertest = ReadText2String(new File("src/test2/ciphertext.txt"));
System.out.println("读入的密文是:\n" + ciphertest);
try {
plaintext = decryptByPrivateKey(ciphertest, privateKey);
} catch (Exception e) {
e.printStackTrace();
} //解密
//将明文写入文件
WriteText2String(plaintext, new File("src/test2/plaintext.txt"));
System.out.println("解密后的明文是:\n" + plaintext);
}
}
}
/**
* 生成公钥和私钥
*/
public static HashMap<String, Object> getKeys(){
HashMap<String, Object> map = new HashMap<String, Object>();
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keypair = keyPairGenerator.generateKeyPair();
//得到公钥
RSAPublicKey publicKey = (RSAPublicKey)keypair.getPublic();
//得到私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keypair.getPrivate();
//放入到map中
map.put("public", publicKey);
map.put("private", privateKey);
return map;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException();
}
}
/**
* 公钥加密
*/
public static String encryptByPublicKey(String data, RSAPublicKey publicKey) throws Exception{
//根据公钥拿到参数n,e
BigInteger n = publicKey.getModulus();
BigInteger e = publicKey.getPublicExponent();
//将明文转化为字节
byte plain_byte[] = data.getBytes("utf-8");
BigInteger m = new BigInteger(plain_byte);
//计算密文
BigInteger c = m.modPow(e, n);
return c.toString();
}
/**
* 私钥解密
*/
public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey) throws Exception{
//获取参数n, d
BigInteger n = privateKey.getModulus();
BigInteger d = privateKey.getPrivateExponent();
//将密文转化为大整数
//byte[] cipher_byte = data.getBytes("utf-8");
BigInteger c = new BigInteger(data);
//解密
BigInteger m = c.modPow(d, n);
return new String(m.toByteArray(), "utf-8");
}
/**
* 写文件
*/
public static void WriteText2String(String output, File file) {
try {
FileOutputStream fout = new FileOutputStream(file);
OutputStreamWriter out = new OutputStreamWriter(fout, "utf-8");
out.write(output);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 读文件
*/
public static String ReadText2String(File file){
StringBuilder result = new StringBuilder();
try{
FileInputStream fin = new FileInputStream(file);
InputStreamReader input = new InputStreamReader(fin, "utf-8");
int content = 0;
while((content = input.read())!=-1){
result.append((char)content);
}
input.close();
}catch(Exception e){
e.printStackTrace();
}
return result.toString();
}
}
测试
eclipse下的测试结果