久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

關于RSA非對稱加密在Android應用中的使用

 WindySky 2017-11-17

大家好,最近的一個項目中為了防止有人直接提交報文,,所以團隊打算在報文的傳輸過程中引入RSA加密的方式,,用以防止這種直接通過報文的提交來進行功能的操作。

下面說下項目的背景,。項目是一款采用H5架構的APP,,我們主要來說明Android端的情況,主要分為三個部分,,首先是一個Android的殼,,是通過原生Android用來承載H5界面以及樣式表等文件,其中涉及到版本控制,,加密解密等功能,,其次是第二部分,第二部分是前臺部分,,涉及到頁面,,Action層,第三部分是后臺部分,,涉及到Service,,其中主要操作包括數(shù)據(jù)的操作,接口的調(diào)用等,。我們想在原生Android層進行報文的加密,,在后臺進行解密校驗等。下面是在原生Android部分做的一個RSA加密解密的Demo,,其中還涉及到關于RSA中需要的公鑰私鑰的生成,。

注意:通過RSA加密之后的密文是一串亂碼,所以在這個Demo項目中我們給了個Base64的編碼方式,,以便有個更好的閱讀和編碼方式不至于出問題,。同樣的,,在解密的時候,我們需要把這個Base64的先解碼,,在使用私鑰進行解密,。

首先我們來看下在原生Android下關于RSA加密解密的Demo的演示圖片

整個布局文件包含4個EditText,2個Button,,在最上面的EditText上輸入需要加密的明文,,點擊加密,把加密的密文放到第二個EditText上,,之后點擊解密,,把加密的密文在解密,整個過程所耗費的時間戳,,打印在最下面的EditText上,。下面是布局代碼:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas./apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.     <EditText  
  7.         android:id="@+id/et1"  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:ems="10" >  
  11.         <requestFocus />  
  12.     </EditText>  
  13.     <LinearLayout  
  14.         android:layout_width="match_parent"  
  15.         android:layout_height="84dp"  
  16.         android:orientation="horizontal" >  
  17.         <Button  
  18.             android:id="@+id/btn1"  
  19.             android:layout_width="wrap_content"  
  20.             android:layout_height="wrap_content"  
  21.             android:text="加密" />  
  22.         <Button  
  23.             android:id="@+id/btn2"  
  24.             android:layout_width="wrap_content"  
  25.             android:layout_height="wrap_content"  
  26.             android:text="解密" />  
  27.     </LinearLayout>  
  28.     <EditText  
  29.         android:id="@+id/et2"  
  30.         android:layout_width="match_parent"  
  31.         android:layout_height="wrap_content"  
  32.         android:ems="10" />  
  33.     <EditText  
  34.         android:id="@+id/et3"  
  35.         android:layout_width="match_parent"  
  36.         android:layout_height="wrap_content"  
  37.         android:ems="10" />  
  38.     <TextView  
  39.         android:id="@+id/textView1"  
  40.         android:layout_width="wrap_content"  
  41.         android:layout_height="wrap_content"  
  42.         android:text="時間:" />  
  43.     <EditText  
  44.         android:id="@+id/et4"  
  45.         android:layout_width="match_parent"  
  46.         android:layout_height="wrap_content"  
  47.         android:ems="10" />  
  48. </LinearLayout>  

關于布局,很簡單,,我們就不多說了,。我們來看看MainActivity,在MainActivity中,,我們加載布局組件,。然后定義2個按鈕的點擊事件

  1. <span style="font-size:14px;">private void initView()  
  2.     {  
  3.         btn1 = (Button) findViewById(R.id.btn1);  
  4.         btn2 = (Button) findViewById(R.id.btn2);  
  5.         btn1.setOnClickListener(this);  
  6.         btn2.setOnClickListener(this);  
  7.   
  8.         et1 = (EditText) findViewById(R.id.et1);  
  9.         et2 = (EditText) findViewById(R.id.et2);  
  10.         et3 = (EditText) findViewById(R.id.et3);  
  11.         et4 = (EditText) findViewById(R.id.et4);  
  12.     }  
  13.   
  14.     @Override  
  15.     public void onClick(View v)  
  16.     {  
  17.         switch (v.getId())  
  18.         {  
  19.         // 加密  
  20.         case R.id.btn1:  
  21.             String source = et1.getText().toString().trim();  
  22.             try  
  23.             {  
  24.                 //根據(jù)字符串String得到PublicKey  
  25.                 PublicKey publicKey = RSAUtils.loadPublicKey(PUCLIC_KEY);  
  26.                 // 加密  
  27.                 byte[] encryptByte = RSAUtils.encryptData(source.getBytes(), publicKey);  
  28.                 // 因為前面公鑰是使用的Base64加密的,這里需要使用Base64解密  
  29.                 String afterencrypt = Base64Utils.encode(encryptByte);  
  30.                 et2.setText(afterencrypt);  
  31.             } catch (Exception e)  
  32.             {  
  33.                 e.printStackTrace();  
  34.             }  
  35.             break;  
  36.         // 解密  
  37.         case R.id.btn2:  
  38.             long now_before = new Date().getTime();  
  39.             String encryptContent = et2.getText().toString().trim();  
  40.             try  
  41.             {  
  42.   
  43.                 // </span><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:10px;">根據(jù)字符串String得到PublicKey</span></span><span style="font-size:14px;">  
  44.                 PrivateKey privateKey = RSAUtils.loadPrivateKey(PRIVATE_KEY);  
  45.                 // 因為RSA加密后的內(nèi)容經(jīng)Base64再加密轉換了一下,,所以先Base64解密回來再給RSA解密,,加密解密的過程中數(shù)據(jù)類型是Byte數(shù)組  
  46.                 byte[] decryptByte = RSAUtils.decryptData(Base64Utils.decode(encryptContent), privateKey);  
  47.                 String decryptStr = new String(decryptByte);  
  48.                 et3.setText(decryptStr);  
  49.             } catch (Exception e)  
  50.             {  
  51.                 e.printStackTrace();  
  52.             }</span>  
  1. <span style="font-size:14px;"><span style="white-space:pre">            </span>//時間戳  
  2.             long now_after = new Date().getTime();  
  3.             long date = now_after - now_before;  
  4.             Toast.makeText(getApplicationContext(), date+"", Toast.LENGTH_LONG).show();  
  5.             et4.setText(""+date);  
  6.             break;  
  7.         default:  
  8.             break;  
  9.         }  
  10.     }</span>  

在initView()方法中,我們通過findViewById找到按鈕和EditText組件,。在onClick(View v)中我們來通過Activity接口的OnClickListener來定義加密和解密的按鈕觸發(fā)事件,。在加密的過程中,我們根據(jù)前面定義的兩個String常量publicKey和私鑰的primaryKey調(diào)用RSAUtil的loadPublicKey方法,,來生成的PublicKey,,解密的過程中,也是如此,,下面是loadPublicKey方法,。

  1. <span style="white-space:pre">    </span>/** 
  2.      * 從字符串中加載公鑰 
  3.      *  
  4.      * @param publicKeyStr 
  5.      *            公鑰數(shù)據(jù)字符串 
  6.      * @throws Exception 
  7.      *             加載公鑰時產(chǎn)生的異常 
  8.      */  
  9.     public static PublicKey loadPublicKey(String publicKeyStr) throws Exception  
  10.     {  
  11.         try  
  12.         {  
  13.             byte[] buffer = Base64Utils.decode(publicKeyStr);  
  14.             KeyFactory keyFactory = KeyFactory.getInstance(RSA);  
  15.             X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);  
  16.             return (RSAPublicKey) keyFactory.generatePublic(keySpec);  
  17.         } catch (NoSuchAlgorithmException e)  
  18.         {  
  19.             throw new Exception("無此算法");  
  20.         } catch (InvalidKeySpecException e)  
  21.         {  
  22.             throw new Exception("公鑰非法");  
  23.         } catch (NullPointerException e)  
  24.         {  
  25.             throw new Exception("公鑰數(shù)據(jù)為空");  
  26.         }  
  27.     }  

根據(jù)傳入的字符串公鑰,拿到PublicKey,。首先給字符串公鑰的進行Base64的解碼,,拿到Byte[],根據(jù)X509EncodedKeySpec給定的編碼密鑰創(chuàng)建一個新的 X509EncodedKeySpec。使用keyFactory的genratePublic方法返回PublicKey,。這樣就拿到了publickey,。

拿到了publicKey,我們調(diào)用RSAUtil中的encryptData(),,來進行加密的操作,。把加密的結果方式EditText上用以顯示,。下面我們看下解密的方法

  1. /** 
  2.      * 用公鑰加密 <br> 
  3.      * 每次加密的字節(jié)數(shù),不能超過密鑰的長度值減去11 
  4.      *  
  5.      * @param data 
  6.      *            需加密數(shù)據(jù)的byte數(shù)據(jù) 
  7.      * @param pubKey 
  8.      *            公鑰 
  9.      * @return 加密后的byte型數(shù)據(jù) 
  10.      */  
  11.     public static byte[] encryptData(byte[] data, PublicKey publicKey)  
  12.     {  
  13.         try  
  14.         {  
  15.             Cipher cipher = Cipher.getInstance(RSA);  
  16.             // 編碼前設定編碼方式及密鑰  
  17.             cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
  18.             // 傳入編碼數(shù)據(jù)并返回編碼結果  
  19.             return cipher.doFinal(data);  
  20.         } catch (Exception e)  
  21.         {  
  22.             e.printStackTrace();  
  23.             return null;  
  24.         }  
  25.     }  

根據(jù)Cipher設置密文的類型為RSA,,調(diào)用init方法設置編碼前編碼方式和密鑰,,傳入編碼數(shù)據(jù)并且放回編碼結果。在把編碼結果放到EditText上用以顯示,。

解密的方法大同小異,。

  1. /** 
  2.      * 從字符串中加載私鑰<br> 
  3.      * 加載時使用的是PKCS8EncodedKeySpec(PKCS#8編碼的Key指令)。 
  4.      *  
  5.      * @param privateKeyStr 
  6.      * @return 
  7.      * @throws Exception 
  8.      */  
  9.     public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception  
  10.     {  
  11.         try  
  12.         {  
  13.             byte[] buffer = Base64Utils.decode(privateKeyStr);  
  14.             // X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);  
  15.             PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);  
  16.             KeyFactory keyFactory = KeyFactory.getInstance(RSA);  
  17.             return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);  
  18.         } catch (NoSuchAlgorithmException e)  
  19.         {  
  20.             throw new Exception("無此算法");  
  21.         } catch (InvalidKeySpecException e)  
  22.         {  
  23.             throw new Exception("私鑰非法");  
  24.         } catch (NullPointerException e)  
  25.         {  
  26.             throw new Exception("私鑰數(shù)據(jù)為空");  
  27.         }  
  28.     }  

  1. /** 
  2.      * 用私鑰解密 
  3.      *  
  4.      * @param encryptedData 
  5.      *            經(jīng)過encryptedData()加密返回的byte數(shù)據(jù) 
  6.      * @param privateKey 
  7.      *            私鑰 
  8.      * @return 
  9.      */  
  10.     public static byte[] decryptData(byte[] encryptedData, PrivateKey privateKey)  
  11.     {  
  12.         try  
  13.         {  
  14.             Cipher cipher = Cipher.getInstance(RSA);  
  15.             cipher.init(Cipher.DECRYPT_MODE, privateKey);  
  16.             return cipher.doFinal(encryptedData);  
  17.         } catch (Exception e)  
  18.         {  
  19.             return null;  
  20.         }  
  21.     }  

最后給大家一串字符串的公鑰和私鑰用以測試使用

  1. //公鑰  
  1. private static String PUCLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCHpicKssPjh3p1aHEtLQrGjvFqYQe9Qwj+P56dj8fnYa3xamxzwZrHzhZCgjjxKBOgTyhwUcCAnjMxp9laIf1KkIvE2RN5Nkaq6NvW5BZEvqUMW7BEh4yiZdAXK+MjLWm2Qhf8j0YEI5R4DEYCjshMJ0wYVpM05K8kNNFP7B+F9QIDAQAB";  
  1. //私鑰  
  2. private static String PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIemJwqyw+OHenVocS0tCsaO8WphB71DCP4/np2Px+dhrfFqbHPBmsfOFkKCOPEoE6BPKHBRwICeMzGn2Voh/UqQi8TZE3k2Rqro29bkFkS+pQxbsESHjKJl0Bcr4yMtabZCF/yPRgQjlHgMRgKOyEwnTBhWkzTkryQ00U/sH4X1AgMBAAECgYBj2pB01KFUdV9U3Bwr6DM9dO4Lo/+hd55AIq7tR3EdR49W3kOVdpgsqu1B6kBmbVz9LigTfmqZg1smG2vpaInd7OLLjgZzumOrArvLQdwScNM5Dn+kZIBJ7N5iVag5aP2KCX9AM/CIqyW6J0nfB9KUffU2YkmE+ZdZurVWm3Y0JQJBAM8pRUVUIu4jfKrntIb3X7Ffo4OoP/ODVAeDmQkJaaNqmDpycm+SqyKZDqZBC8PaFBRwW9UDVcuZvL7lNcmoS+cCQQCnoO6S0ZkQhgWpS0AmmwcCK/nsmc2XhOLf1rQ1dm4EKDSEvAkG67cOsR/2Usl6IYlGlQKJyZwabKbC3Z/WZgPDAkA+5n4U9d4BRp8k2WO0E0pn9e0VHbIFQ1vxSCDgYI5Fwyjjnjpm7DawM58CFf/3gLDWH+OSQwf64PwxTjFNwJ8DAkAw8gy3UfwflwKQLCjPHPUu7ShMrZwaYfLc6RQ1iB8Xl6W+HCmGm80XvSBYDFRIFQLAWUIkeXnbPV50B8JkF+WBAkA7oVRBgJcDcx7KBuRCwrd+goCslV6hz36Uc4CdJsZfyVDcLFthFgFGoePWSPh08POGJIHrwt+SrWlKLsoXWNbu"  

下面把項目源碼(RSADemo)上傳到CSDN供大家下載,,在提供一個項目(Keys)可以用來生成公鑰和私鑰,。

RSADemo:http://download.csdn.net/detail/a514224717/9216251

Keys:http://download.csdn.net/detail/a514224717/9216337


    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,,請點擊一鍵舉報,。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多