1、rsa公钥、秘钥生成接口
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.crypto.Cipher;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.zkgj.common.AESUtil;
import com.zkgj.common.RSA;
import sun.misc.BASE64Encoder;
@Controller
@RequestMapping("/views")
public class ViewController {
@Autowired
private RSA rsa;
@RequestMapping("rsaData")
@ResponseBody
public String[] rsaData(int num) {
int[] pp = getPubPri(num);
System.out.println(pp[0]+" "+pp[1]);
// RSA rsa = new RSA();
// 获取秘钥
rsa.mKey(pp[0],pp[1]);
//随机数
int index = (int)(Math.random()*1000);
System.out.println("===========明文:"+index);
// 加密
int cryptograph = rsa.encrypt(index);
String p = pp[0]*pp[1]+"";
String[] arrStr = {cryptograph+"",p};
return arrStr;
}
//获取公钥私钥中的两个质数
public int[] getPubPri(int num) {
int maxNum = 0;
int minNum = 2<<num;
for(int i=0;i<=num;i++) {
maxNum+=2<<i;
}
System.out.println("maxNum:"+maxNum+", minNum:"+minNum);
List<int[]> listInt = new ArrayList<>();
for(int even=minNum;even<maxNum;even++) {
// 如果i和even-i同为质数时,输出结果
for (int i = 2; i <= even / i; i++) {
if (prime(i)&&even%i==0&& prime(even/i)) {
// System.out.println(even + "=" + i + "+" + (even - i));
int[] arr = {i,even/i};
listInt.add(arr);
}
}
}
System.out.println("质数符合的数量:"+listInt.size());
//随机数
int index = (int)(Math.random()*(listInt.size()-1));
System.out.println("随机数index:"+index);
return listInt.get(index);
}
// 判断数字是否为质数方法
public static boolean prime(int n) {
boolean flag = true;
if (n == 2 || n == 3) {
} else {
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
flag = false;
break;
}
}
}
return flag;
}
}
package com.zkgj.common;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Component;
@Component
public class RSA {
PublicKey publicKey = new PublicKey();
PrivateKey privateKey = new PrivateKey();
public void mKey(int a,int b) {
// System.out.println("###01)选两个质数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(13,29);
// // 原文
// 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);
// }
}
package com.zkgj.common;
public class PublicKey {
int c;
int e;
@Override
public String toString() {
return "PublicKey [c=" + c + ", e=" + e + "]";
}
}
package com.zkgj.common;
public class PrivateKey {
int c;
int f;
@Override
public String toString() {
return "PrivateKey [c=" + c + ", f=" + f + "]";
}
}
2、调用接口破解
package http;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import sun.misc.BASE64Encoder;
public class TestHttp {
public static String doGetTest(String url) {
// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
// 创建Get请求
HttpGet httpGet = new HttpGet(url);
// 响应模型
CloseableHttpResponse response = null;
try {
// 由客户端执行(发送)Get请求
response = httpClient.execute(httpGet);
// // 从响应模型中获取响应实体
HttpEntity responseEntity = response.getEntity();
// System.out.println("响应状态为:" + response.getStatusLine());
if (responseEntity != null) {
// System.out.println("响应内容长度为:" + responseEntity.getContentLength());
// System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
return EntityUtils.toString(responseEntity);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 释放资源
if (httpClient != null) {
httpClient.close();
}
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* rsa破解
*/
@Test
public void rsaPoJie() {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("获取加密数据开始:"+df.format(new Date()));
String url = "http://localhost:8080/views/rsaData?num=";
JSONArray arr = (JSONArray) JSON.parse(TestHttp.doGetTest(url+10));
System.out.println("获取加密数据结束:"+df.format(new Date()));
System.out.println("破解数据开始:"+df.format(new Date()));
String data = arr.getString(0);
String str = arr.getString(1);
int[] ints = baolipojieRsa(str);
if(ints==null) {
System.out.println(str+"质数为空");
return ;
}
System.out.println("质数:"+ints[0]+" "+ints[1]);
RSA rsa = new RSA();
// 获取秘钥
rsa.mKey(ints[0],ints[1]);
System.out.println("密文:" + data);
// 解密
int after = rsa.decrypt(Integer.parseInt(data));
System.out.println("破解数据结束:"+df.format(new Date()));
System.out.println("解密后:" + after);
}
public int[] baolipojieRsa(String str) {
int bl = Integer.parseInt(str);
int[] pp = getPubPri(bl);
return pp;
}
//获取公钥私钥中的两个质数
public int[] getPubPri(int num) {
int even=num;
// 如果i和even-i同为质数时,输出结果
for (int i = 2; i <= even / i; i++) {
if (prime(i)&&even%i==0&& prime(even/i)) {
return new int[] {i,even/i};
}
}
return null;
}
// 判断数字是否为质数方法
public static boolean prime(int n) {
boolean flag = true;
if (n == 2 || n == 3) {
} else {
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
flag = false;
break;
}
}
}
return flag;
}
}