Java Web項目RSA加密,javawebrsa加密

來源:互聯網
上載者:User

Java Web項目RSA加密,javawebrsa加密

最近做的一個項目,伺服器為Java,採用SSH架構,用戶端為Android和IOS。當使用者登入時,從用戶端向伺服器提交使用者名稱和密碼。這就存在一個問題,如果資料包在網路上被其他人截取了,密碼就有可能泄露。

可以採用Base64對密碼編碼,但是Base64要進行解碼是很容易的事。

另一種方法是對密碼進行MD5加密,MD5是無法復原的,只能加密不能解密。但是其他人截取了密碼的MD5字串以後,可以原封不動的將MD5加密後的字串提交給伺服器,伺服器肯定會判斷這是正確的密碼,這樣還是可以登入進去。

解決的方法就只能採用密碼編譯演算法了。密碼編譯演算法分為對稱式加密和非對稱式加密。對稱式加密演算法,加密和解密使用相同的密鑰,密鑰在網路傳輸的過程中有可能被截取,所以不是很安全。非對稱式加密,使用公開金鑰加密,只能使用私密金鑰解密,公開金鑰是公開的,私密金鑰是不公開的。即使在傳遞的過程中,公開金鑰被其他人擷取了也無所謂,因為公開金鑰是用來加密的,只有私密金鑰才能解密,而私密金鑰是不會傳遞的,也就不可能被其他人擷取。

非對稱式加密最常用的就是RSA演算法,RSA演算法是由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的,取了他們姓的第一個字母來命名。RSA演算法的原理就不講了。密鑰長度為768的RSA演算法有可能被破解,密鑰長度為1024的RSA演算法還沒有被破解,所以可以認為密鑰長度為1024的RSA演算法是比較安全的。但是RSA演算法的計算量大,一般只用於關鍵資訊的加密,如密碼、對稱式加密演算法的密鑰等。在我們的項目中,就使用RSA演算法對使用者密碼進行加密。具體的步驟如下:

1. 用戶端向伺服器申請密鑰;

2. 伺服器接收到用戶端的申請以後,產生一對密鑰,將公開金鑰發給用戶端,私密金鑰自己儲存;

3. 用戶端接收到公開金鑰以後,使用公開金鑰對密碼加密,然後將密文發給伺服器;

4. 伺服器接收到密文以後,使用私密金鑰解密,判斷是否是正確的密碼。

下面是關鍵代碼。

產生密鑰和加密、解密的代碼:

/**      * 產生公開金鑰和私密金鑰      * @throws NoSuchAlgorithmException       *      */      public static HashMap<String, Object> getKeys() throws NoSuchAlgorithmException{          HashMap<String, Object> map = new HashMap<String, Object>();          KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");          keyPairGen.initialize(1024);          KeyPair keyPair = keyPairGen.generateKeyPair();          RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();          RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();          map.put("public", publicKey);          map.put("private", privateKey);          return map;      }         /**      * 使用模和指數產生RSA公開金鑰      * 注意:【此代碼用了預設補位方式,為RSA/None/PKCS1Padding,不同JDK預設的補位方式可能不同,如Android預設是RSA      * /None/NoPadding】      *       * @param modulus      *            模      * @param exponent      *            指數      * @return      */      public static RSAPublicKey getPublicKey(String modulus, String exponent) {          try {              BigInteger b1 = new BigInteger(modulus);              BigInteger b2 = new BigInteger(exponent);              KeyFactory keyFactory = KeyFactory.getInstance("RSA");              RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);              return (RSAPublicKey) keyFactory.generatePublic(keySpec);          } catch (Exception e) {              e.printStackTrace();              return null;          }      }        /**      * 使用模和指數產生RSA私密金鑰      * 注意:【此代碼用了預設補位方式,為RSA/None/PKCS1Padding,不同JDK預設的補位方式可能不同,如Android預設是RSA      * /None/NoPadding】      *       * @param modulus      *            模      * @param exponent      *            指數      * @return      */      public static RSAPrivateKey getPrivateKey(String modulus, String exponent) {          try {              BigInteger b1 = new BigInteger(modulus);              BigInteger b2 = new BigInteger(exponent);              KeyFactory keyFactory = KeyFactory.getInstance("RSA");              RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(b1, b2);              return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);          } catch (Exception e) {              e.printStackTrace();              return null;          }      }        /**      * 公開金鑰加密      *       * @param data      * @param publicKey      * @return      * @throws Exception      */      public static String encryptByPublicKey(String data, RSAPublicKey publicKey)              throws Exception {          Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");          cipher.init(Cipher.ENCRYPT_MODE, publicKey);          // 模長          int key_len = publicKey.getModulus().bitLength() / 8;          // 加密資料長度 <= 模長-11          String[] datas = splitString(data, key_len - 11);          String mi = "";          //如果明文長度大於模長-11則要區塊編碼器          for (String s : datas) {              mi += bcd2Str(cipher.doFinal(s.getBytes()));          }          return mi;      }        /**      * 私密金鑰解密      *       * @param data      * @param privateKey      * @return      * @throws Exception      */      public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey)              throws Exception {          Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");          cipher.init(Cipher.DECRYPT_MODE, privateKey);          //模長          int key_len = privateKey.getModulus().bitLength() / 8;          byte[] bytes = data.getBytes();          byte[] bcd = ASCII_To_BCD(bytes, bytes.length);          System.err.println(bcd.length);          //如果密文長度大於模長則要分組解密          String ming = "";          byte[][] arrays = splitArray(bcd, key_len);          for(byte[] arr : arrays){              ming += new String(cipher.doFinal(arr));          }          return ming;      } 

伺服器收到用戶端的請求時,產生一對密鑰:

                HashMap<String, Object> mymap = RSAUtils.getKeys();                // 產生公開金鑰和私密金鑰                  RSAPublicKey publicKey = (RSAPublicKey) mymap.get("public");                  RSAPrivateKey privateKey = (RSAPrivateKey) mymap.get("private");                 // 模                  String modulus = publicKey.getModulus().toString();                  // 公開金鑰指數                  String public_exponent = publicKey.getPublicExponent().toString();                  // 私密金鑰指數                  String private_exponent = privateKey.getPrivateExponent().toString();                 // 使用模和指數產生公開金鑰和私密金鑰                  RSAPublicKey pubKey = RSAUtils.getPublicKey(modulus, public_exponent);                  RSAPrivateKey priKey = RSAUtils.getPrivateKey(modulus, private_exponent);

將其中的模和私密金鑰指數發給用戶端,用戶端收到以後,使用getPrivateKey(String modulus, String exponent)產生私密金鑰,使用私密金鑰對密碼加密,然後發給伺服器。伺服器收到密文以後,使用decryptByPrivateKey(String data, RSAPrivateKey privateKey)解密,獲得密碼明文,然後就可以判斷密碼是否正確。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.