低位rsa公鑰、私鑰生成破解

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

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章