Java中RSA非對稱金鑰加解密使用樣本

來源:互聯網
上載者:User

標籤:

一、簡介: RSA密碼編譯演算法是最常用的非對稱式加密演算法,CFCA在認證服務中離不了它。RSA是第一個比較完善的公開密鑰演算法,它既能用於加密,也能用於數位簽章。這個演算法經受住了多年深入的密碼分析,雖然密碼分析者既不能證明也不能否定RSA的安全性,但這恰恰說明該演算法有一定的可信性,目前它已經成為最流行的公開密鑰演算法。

二、RSA的公開金鑰、私密金鑰的組成,以及加密、解密的公式可見於下表

三、使用方式:

①  假設A、B機器進行通訊,已A機器為主;

②  A首先需要用自己的私密金鑰為發送請求資料簽名,並將公開金鑰一同發送給B;

③  B收到資料後,需要用A發送的公開金鑰進行驗證,已確保收到的資料是未經篡改的;

④  B驗簽通過後,處理邏輯,並把處理結果返回,返回資料需要用A發送的公開金鑰進行加密(公開金鑰加密後,只能用配對的私密金鑰解密);

⑤  A收到B返回的資料,使用私密金鑰解密,至此,一次資料互動完成。

四、程式碼範例:

    1. 第一步擷取私密金鑰,為簽名做準備。
      /**      * 讀取私密金鑰  返回PrivateKey      * @param path  包含私密金鑰的憑證路徑      * @param password  私密金鑰認證密碼      * @return 返回私密金鑰PrivateKey      * @throws KeyStoreException      * @throws NoSuchAlgorithmException      * @throws CertificateException      * @throws IOException      * @throws UnrecoverableKeyException      */      private static PrivateKey getPrivateKey(String path,String password)              throws KeyStoreException, NoSuchAlgorithmException, CertificateException,              IOException, UnrecoverableKeyException {          KeyStore ks = KeyStore.getInstance("PKCS12");          FileInputStream fis = new FileInputStream(path);          char[] nPassword = null;          if ((password == null) || password.trim().equals("")) {              nPassword = null;          } else {              nPassword = password.toCharArray();          }          ks.load(fis, nPassword);          fis.close();          Enumeration<String> en = ks.aliases();          String keyAlias = null;          if (en.hasMoreElements()) {              keyAlias = (String) en.nextElement();          }             return (PrivateKey) ks.getKey(keyAlias, nPassword);      }  

       

       
    2. 簽名樣本  通過第一步得到的私密金鑰,進行簽名操作,具體請看以下代碼:
      /**      * 私密金鑰簽名: 簽名方法如下:BASE64(RSA(MD5(src),privatekey)),其中src為需要簽名的字串, privatekey是商戶的CFCA認證私密金鑰。      * @param plainText 待簽名字串      * @param path 簽名私密金鑰路徑      * @param password  簽名私密金鑰密碼      * @return 返回簽名後的字串      * @throws Exception      */      public static String sign(String plainText,String path,String password)              throws Exception  {          /*          * MD5加密          */          MessageDigest md5 = MessageDigest.getInstance("MD5");          md5.update(plainText.getBytes("utf-8"));          byte[] digestBytes = md5.digest();          /*          * 用私密金鑰進行簽名 RSA          * Cipher負責完成加密或解密工作,基於RSA          */          Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");          //ENCRYPT_MODE表示為加密模式          cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey(path, password));          //加密          byte[] rsaBytes = cipher.doFinal(digestBytes);          //Base64編碼          return Base64.byteArrayToBase64(rsaBytes); 

       

       
    3. B收到資料後,需要使用A提供的公開金鑰資訊進行驗簽,此處使用公開金鑰的N、E進行驗簽 首先通過公開金鑰N、E得到公開金鑰PublicKey,如下:

       

      /**       * 根據公開金鑰n、e產生公開金鑰      * @param modulus   公開金鑰n串      * @param publicExponent  公開金鑰e串      * @return 返回公開金鑰PublicKey      * @throws Exception      */      public static PublicKey getPublickKey(String modulus, String publicExponent)              throws Exception {          KeySpec publicKeySpec = new RSAPublicKeySpec(                  new BigInteger(modulus, 16), new BigInteger(publicExponent, 16));          KeyFactory factory = KeyFactory.getInstance("RSA");          PublicKey publicKey = factory.generatePublic(publicKeySpec);          return publicKey;      }  

       

       

      得到公開金鑰PublicKey後,再去驗證簽名,代碼如下:

      /**      * 用密鑰憑證進行驗簽      * @param message  簽名之前的原文      * @param cipherText  簽名      * @param pubKeyn 公開金鑰n串      * @param pubKeye 公開金鑰e串      * @return boolean 驗簽成功為true,失敗為false      * @throws Exception      */      public static boolean verify(String message, String cipherText,String pubKeyn,              String pubKeye) throws Exception {          Cipher c4 = Cipher.getInstance("RSA/ECB/PKCS1Padding");          // 根據密鑰,對Cipher對象進行初始化,DECRYPT_MODE表示解密模式          c4.init(Cipher.DECRYPT_MODE, getPublickKey(pubKeyn,pubKeye));          // 解密          byte[] desDecTextBytes = c4.doFinal(Base64.base64ToByteArray(cipherText));          // 得到前置對原文進行的MD5          String md5Digest1 = Base64.byteArrayToBase64(desDecTextBytes);          MessageDigest md5 = MessageDigest.getInstance("MD5");          md5.update(message.getBytes("utf-8"));          byte[] digestBytes = md5.digest();          // 得到商戶對原文進行的MD5          String md5Digest2 = Base64.byteArrayToBase64(digestBytes);          // 驗證簽名          if (md5Digest1.equals(md5Digest2)) {              return true;          } else {              return false;          }      }  

      至此,簽名驗簽已經完畢

    4. 提供一個從.cer檔案讀取公開金鑰的方法:
      /**      * 讀取公開金鑰cer      * @param path .cer檔案的路徑  如:c:/abc.cer      * @return  base64後的公開金鑰串      * @throws IOException      * @throws CertificateException      */      public static String getPublicKey(String path) throws IOException,      CertificateException{          InputStream inStream = new FileInputStream(path);          ByteArrayOutputStream out = new ByteArrayOutputStream();          int ch;          String res = "";          while ((ch = inStream.read()) != -1) {              out.write(ch);          }          byte[] result = out.toByteArray();          res = Base64.byteArrayToBase64(result);          return res;      }  

       

       
    5. 附上所有代碼: http://pan.baidu.com/share/link?shareid=23044&uk=2986731784
      本文轉自:http://www.huosen.net/archives/124.html

Java中RSA非對稱金鑰加解密使用樣本

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.