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;
}
}