Java RSA公鑰加密,私鑰解密算法的嘗試

  寫這篇博客實際上是有點意外的,來源最初也算是入職當前這家公司算吧,因爲項目要求數據幾乎都進行了加密(政府項目麼!!!),當時看到這塊就想好好看看這塊的東西,苦於時間一直尋找不開,慢慢的都忘記了,突然有天在網上看到一些關於加密的博客,討論到說支付寶這樣的商業軟件加密是如何進行操做,後來瞭解了下,因爲我是作android開發的因此我想固然的就下載了一個支付寶的android版本,進階着就是火燒眉毛的改後綴,而後看看內部構造,發現支付寶的.so文件是超級多,那麼問題來了,對於支付寶這樣當量的用戶,放到android 的java層去加密確定是不合適的,這裏來源於java語言的不安全性的考慮。多的不說apk的反編譯,一旦反編譯了看到了你java加密算法,臥槽,那問題就大了去了,估計馬雲爸爸想殺人的新都有,那麼很顯然對於支付寶而言確定不能這麼幹,那麼多的.so就很能說明問題了(加密是經過jni使用C代碼實現的加密)。java

  那麼到了這裏加密基本算是確認了,要是想保證你的數據的安全放到.so裏會更加的安全(android上纔有的東西哈).android

  說道加密那麼就進入到本篇博客的主題,加密算法之RSA非對稱的加密算法。直譯爲私鑰加密,公鑰解密。其實也是很簡單了,私鑰只要你本身知道就行了,這樣就能保證加密的數據只能你本身才能解密。公鑰能夠公開,公鑰僅僅是用於加密的,是沒法用於去解密數據的。算法

  RSA非對稱的算法,也是不可逆的,不可逆就是沒法根據公鑰獲得其算法,而後根據公鑰去獲去私鑰!!!安全

  好了 ,基本的講解就這些吧,緊接着一塊兒來看下關於Java中的一些RSA的使用吧!!!dom

  Java使用分爲三步走戰略!!!測試

    1,生成私鑰和祕鑰編碼

    2,公鑰加密
加密

    3,私鑰解密spa

  看到這裏是否是很so easy.code

  java代碼生成私鑰和祕鑰以下代碼:

/**
	 *生成私鑰  公鑰 
	 */
	public static void geration(){
		KeyPairGenerator keyPairGenerator;
		try {
			keyPairGenerator = KeyPairGenerator.getInstance("RSA");
			SecureRandom secureRandom = new SecureRandom(new Date().toString().getBytes());  
	        keyPairGenerator.initialize(1024, secureRandom);  
	        KeyPair keyPair = keyPairGenerator.genKeyPair();  
	        byte[] publicKeyBytes = keyPair.getPublic().getEncoded();  
	        FileOutputStream fos = new FileOutputStream(PUBLIC_KEY_PATH);   
	        fos.write(publicKeyBytes);   
	        fos.close();  
	        byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();  
	        fos = new FileOutputStream(PRIVATE_KEY_PATH);   
	        fos.write(privateKeyBytes);   
	        fos.close();  
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}   
	}

  

  獲去公鑰代碼以下:

	/**
	 * 獲取公鑰
	 * @param filename
	 * @return
	 * @throws Exception
	 */
	public static PublicKey getPublicKey(String filename) throws Exception {  
        File f = new File(filename);  
        FileInputStream fis = new FileInputStream(f);   
        DataInputStream dis = new DataInputStream(fis);  
        byte[] keyBytes = new byte[(int)f.length()];
        dis.readFully(keyBytes);   
        dis.close(); 
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);  
        KeyFactory kf = KeyFactory.getInstance("RSA");   
        return kf.generatePublic(spec);  
    }  

  獲去私鑰的代碼以下:

   /**
     * 獲取私鑰
	 * @param filename
	 * @return
	 * @throws Exception
	 */
	public static PrivateKey getPrivateKey(String filename)throws Exception {  
        File f = new File(filename);  
        FileInputStream fis = new FileInputStream(f);  
        DataInputStream dis = new DataInputStream(fis);  
        byte[] keyBytes = new byte[(int)f.length()];  
        dis.readFully(keyBytes);  
        dis.close();  
        PKCS8EncodedKeySpec spec =new PKCS8EncodedKeySpec(keyBytes);  
        KeyFactory kf = KeyFactory.getInstance("RSA");  
        return kf.generatePrivate(spec);  
      }  
	

  測試如上代碼的可用性:

	public static void main(String[] args) {
		
		geration();
		 
		String input = "!!!hello world!!!";  
        RSAPublicKey pubKey;
        RSAPrivateKey privKey;
        byte[] cipherText;
        Cipher cipher;
		try {
			cipher = Cipher.getInstance("RSA");          
			pubKey = (RSAPublicKey) getPublicKey(PUBLIC_KEY_PATH);
			privKey = (RSAPrivateKey) getPrivateKey(PRIVATE_KEY_PATH);
			
			cipher.init(Cipher.ENCRYPT_MODE, pubKey);  
			cipherText = cipher.doFinal(input.getBytes());  
			//加密後的東西  
	        System.out.println("cipher: " + new String(cipherText));          
	        //開始解密  
	        cipher.init(Cipher.DECRYPT_MODE, privKey);   
	        byte[] plainText = cipher.doFinal(cipherText);  
	        System.out.println("publickey: " + Base64.getEncoder().encode(cipherText));
	        System.out.println("plain : " + new String(plainText)); 
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}  
    }  

  測試結果以下:

cipher: D?:?=羖O縜?,^輈?$偞/致?2懁B鏣靴臧??2e嗀|?,w饞i纂W俞:&圼?G6?弒橰H桞℉鬜?=)^呸b???;皒Ddm`苣+.+?
?:&	??#f-?扴8eE]?(
plain : !!!hello world!!!

  如上是RSA加密的java版本

  

  固然上述最終生成的byte寫入到了一個文件中。若是你感受這樣和你不方便你也能夠直接用base64編碼成一個字符串,保留下來。

  

使用Base64.getEncoder().encodeToString(keyBytes)進行編譯

使用Base64.getDecoder().decode(PUBLIC_KEY)進行解碼
相關文章
相關標籤/搜索