RSA2實例詳解

本文介紹RSA2加密與解密,RSA2是RSA的增強版本,在密鑰長度上採用2048, RSA2比RSA更安全,更可靠, 本人的另外一篇文章RSA已經發表,有想了解的能夠點開下面的RSA文章, 但RSA2在明文的加密數據長度上有個小缺陷,只能對不超過密文長度的明文進行加密java

實例下載數組

工具集下載安全

RSA文章: http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=322mvc

關於RSA2的理論其實與RSA相似,想具體瞭解的能夠參考上面的連接,下面直接上代碼dom

 

函數test1中使用RSA2的私鑰對數據進行加密,使用RSA2的公鑰對數據進行解密ide

下面代碼中的密鑰字符串是對密鑰字節數組進行了base64加密而獲得的,在使用時將密串進行base64解密便可函數

複製代碼

//私鑰加密,公鑰解密
public static void test1(String src){
    try {
        //1.初始化密鑰
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
         
        //String strPublicKey = Base64.encodeBase64String(rsaPublicKey.getEncoded());
        //String strPrivateKey = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
         
        String strPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgdQVFyYvJQ38hBAEJ3Zr3BJFtp
         XauN83ghWtgJ1m92XvshGomjEgKpAxyQf9HqqvZB8U0nW+eNIgTAcKZemIQci/6/+oXMhu+WgdIxlJGLzvhZWa
         z7UzfKfCFTiUAh6X+hHRlPisekt/y70pbpkxd+GVbmVF5bGxSBnlhdnKa+lAbZd2sO8jv3fzSD0w3dWDmjKg9O
         jPxXt1jnwbj0BmwN4TDiMPSmmDBEz7JHadb6A99cswCVXWz3pgioHzq20ipDZDUdAphtgcyT6TO1eZdwHth1tw
         0UIcPfUmx5wMGSVBkP/42/AnvG8Y9ROwvg9XpCu2HI+o/n7Ljht5tknDKwIDAQAB";
          
        String strPrivateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCB1BUXJi8lDfy
          EEAQndmvcEkW2ldq43zeCFa2AnWb3Ze+yEaiaMSAqkDHJB/0eqq9kHxTSdb540iBMBwpl6YhByL/r/6hcyG75aB0j
          GUkYvO+FlZrPtTN8p8IVOJQCHpf6EdGU+Kx6S3/LvSlumTF34ZVuZUXlsbFIGeWF2cpr6UBtl3aw7yO/d/NIPTDd1YO
          aMqD06M/Fe3WOfBuPQGbA3hMOIw9KaYMETPskdp1voD31yzAJVdbPemCKgfOrbSKkNkNR0CmG2BzJPpM7V5l3Ae2HW3DRQh
          w99SbHnAwZJUGQ//jb8Ce8bxj1E7C+D1ekK7Ycj6j+fsuOG3m2ScMrAgMBAAECggEAEnDqkgA1gCDtdmDEBkr25SqfRmEg
          0VO7kbm8jGFPR+Lt2jBR75z8wa77s190H9AE28bicUaSSJ0oQ0RYwMMcPKPkRwRoiM1bngeg4+Rqkp37s9DdTZWie5lkoxk
          HRQnNcpLnXy63aSOiQnFbGj+eXDXpwOWXuRm1YdVz2cBm1U71Fy4pKNKU8B/Z/gLucnxotXWVQjhguKIrY0BEdH/0TJlPzl
          AQQYYuCItA7gJUNivCv0ecDswG0AchkdAIwbjRFS9Jpc4sWkvlgdYaP33uNjzXQrG7QZxSaCADorB8vFM/c7MxJZuS5hOvI
          ZN5FYTZJ7NW6ujepHaZKaPfexjYCQKBgQD6CIVP0I6jsqhLsqXr89x2hNqnvxhynfot3bGJzeGhuGYnAnfI/YzhekZ25mq
          dY5yYkTY2gWIgwf1f3HxEOY0ZuydTjrppkBnngGs2L03x2F+ZEnHYrg3DwUdahRxxqI/DyzKOUWUOt48ESaoMLUUFmdTrR7
          Bw5inS1WNhirv/XQKBgQCE7TfDTGe2O9CdKl6UGm6qFgXroWesBle5/2WDklVevo70xgOzKFtkVMbsRMb+9e6qZZbyCjDh6
          gO1xUVVMhYUBTxmLPdGdGmRVdEGDB2EonuRfhkImq1ftRID9LlstkUkQr70iwS+t7+f7H07fL6WOdiMkGbx/No/hze4Rwu
          MJwKBgH/nHfL/WAhLWyYmBBSYkb2bJpNLAQGY6KLP1oMM65Aj2TW5YHdTpN6vAx7NrdpHW5L8LYRiWUUylx+TlYn8+r4f
          6/UlfRyFF4tCORXlyvSdYAHY2p4iI25xD8QxdaR6uthIuNrurkiCA8oIuNEz0ywTTkTxTkPiqaBtgkIiixsNAoGAfk/8oTT
          FiMGmJvLQFORZLH7o+VPS9ADC9BfhGvm+7d0eczKG6YP79Icqz/E7N6PzOzB2E2HjuYlqJRxkGeUSXcvr7Rvljampd1W
          Y3qo8koDj8wlkOGzjOwMRL3kpikhZw285jZ9czu5ExW8wQYr0gERPpqLBcEnaCmwvYokATBkCgYEA1lPCbn8um4e7faqDV
          Ym0H6+2stYUHC4ucrmHw3FbvS4ko9omWMj5xyPDUP2x/Ls2AfJSZR9lqPty8yqDTObHiuEPv8q0e0qw+PJIp4kaY8tAFwc
          IXlphANJIeKgAmbfEYyboKzG8Qe+u5gA1gYKFl5zr/WZX0drqM5NG/CZzqfQ=";
         
        System.out.println("Public Key : " + strPublicKey); 
        System.out.println("Private Key : " + strPrivateKey); 
         
         
        //1.私鑰加密加密
        byte[] keyPrivateBytes = Base64.decodeBase64(strPrivateKey);
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyPrivateBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(src.getBytes());
        System.out.println("私鑰加密、公鑰解密——加密 : " + Base64.encodeBase64String(result));
         
         
         
         
        //2.公鑰解密
        byte[] keyPublicBytes = Base64.decodeBase64(strPublicKey);
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyPublicBytes);
        keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        result = cipher.doFinal(result);
        System.out.println("私鑰加密、公鑰解密——解密:" + new String(result));
         
         
    } catch (Exception e) {
        e.printStackTrace();
    }
}

複製代碼

注意:因爲密鑰長度的緣由,明文的長度有必定的限制, 若是明文數據太長的話,會報以下錯誤工具

javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:337)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:382)
    at javax.crypto.Cipher.doFinal(Cipher.java:2087)
    at com.wisdomdd.rsa2.RSA2Test.test2(RSA2Test.java:94)
    at com.wisdomdd.rsa2.RSA2Test.main(RSA2Test.java:118)

報錯緣由:加密

無論明文長度是多少,RSA 生成的密文長度老是固定的。3d

可是明文長度不能超過密鑰長度。好比 Java 默認的 RSA 加密實現不容許明文長度超過密鑰長度減去 11(單位是字節,也就是 byte)。也就是說,若是咱們定義的密鑰(咱們能夠經過 java.security.KeyPairGenerator.initialize(int keysize) 來定義密鑰長度)長度爲 1024(單位是位,也就是 bit),生成的密鑰長度就是 1024位 / 8位/字節 = 128字節,那麼咱們須要加密的明文長度不能超過 128字節 -

11 字節 = 117字節。也就是說,咱們最大能將 117 字節長度的明文進行加密,不然會出問題(拋諸如 javax.crypto.IllegalBlockSizeException: Data must not be longer than 53 bytes 的異常)

http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=322 一文中在加密與解密時使用小技藝對加密與解密的字節進行拆份,解決明文長度太長的問題

 

 

函數test2中使用RSA2的公鑰對數據進行加密,使用RSA2私鑰對數據進行解密

複製代碼

public static void test2(String src){
    try {
        //1.初始化密鑰
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
         
        //String strPublicKey = Base64.encodeBase64String(rsaPublicKey.getEncoded());
        //String strPrivateKey = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
         
        String strPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgdQVFyYvJQ38hBAEJ3Zr3BJ
         FtpXauN83ghWtgJ1m92XvshGomjEgKpAxyQf9HqqvZB8U0nW+eNIgTAcKZemIQci/6/+oXMhu+WgdIxlJGLzvhZWaz
         7UzfKfCFTiUAh6X+hHRlPisekt/y70pbpkxd+GVbmVF5bGxSBnlhdnKa+lAbZd2sO8jv3fzSD0w3dWDmjKg9OjPxXt
         1jnwbj0BmwN4TDiMPSmmDBEz7JHadb6A99cswCVXWz3pgioHzq20ipDZDUdAphtgcyT6TO1eZdwHth1tw0UIcPfUmx
         5wMGSVBkP/42/AnvG8Y9ROwvg9XpCu2HI+o/n7Ljht5tknDKwIDAQAB";
          
        String strPrivateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCB1BUXJi8lDfyEEAQndm
         vcEkW2ldq43zeCFa2AnWb3Ze+yEaiaMSAqkDHJB/0eqq9kHxTSdb540iBMBwpl6YhByL/r/6hcyG75aB0jGUkYvO+FlZrP
         tTN8p8IVOJQCHpf6EdGU+Kx6S3/LvSlumTF34ZVuZUXlsbFIGeWF2cpr6UBtl3aw7yO/d/NIPTDd1YOaMqD06M/Fe3WOfB
         uPQGbA3hMOIw9KaYMETPskdp1voD31yzAJVdbPemCKgfOrbSKkNkNR0CmG2BzJPpM7V5l3Ae2HW3DRQhw99SbHnAwZJUGQ
         //jb8Ce8bxj1E7C+D1ekK7Ycj6j+fsuOG3m2ScMrAgMBAAECggEAEnDqkgA1gCDtdmDEBkr25SqfRmEg0VO7kbm8jGFPR+
         Lt2jBR75z8wa77s190H9AE28bicUaSSJ0oQ0RYwMMcPKPkRwRoiM1bngeg4+Rqkp37s9DdTZWie5lkoxkHRQnNcpLnXy63
         aSOiQnFbGj+eXDXpwOWXuRm1YdVz2cBm1U71Fy4pKNKU8B/Z/gLucnxotXWVQjhguKIrY0BEdH/0TJlPzlAQQYYuCItA7g
         JUNivCv0ecDswG0AchkdAIwbjRFS9Jpc4sWkvlgdYaP33uNjzXQrG7QZxSaCADorB8vFM/c7MxJZuS5hOvIZN5FYTZJ7NW
         6ujepHaZKaPfexjYCQKBgQD6CIVP0I6jsqhLsqXr89x2hNqnvxhynfot3bGJzeGhuGYnAnfI/YzhekZ25mqdY5yYkTY2gW
         Igwf1f3HxEOY0ZuydTjrppkBnngGs2L03x2F+ZEnHYrg3DwUdahRxxqI/DyzKOUWUOt48ESaoMLUUFmdTrR7Bw5inS1WNh
         irv/XQKBgQCE7TfDTGe2O9CdKl6UGm6qFgXroWesBle5/2WDklVevo70xgOzKFtkVMbsRMb+9e6qZZbyCjDh6gO1xUVVMh
         YUBTxmLPdGdGmRVdEGDB2EonuRfhkImq1ftRID9LlstkUkQr70iwS+t7+f7H07fL6WOdiMkGbx/No/hze4RwuMJwKBgH/n
         HfL/WAhLWyYmBBSYkb2bJpNLAQGY6KLP1oMM65Aj2TW5YHdTpN6vAx7NrdpHW5L8LYRiWUUylx+TlYn8+r4f6/UlfRyFF4
         tCORXlyvSdYAHY2p4iI25xD8QxdaR6uthIuNrurkiCA8oIuNEz0ywTTkTxTkPiqaBtgkIiixsNAoGAfk/8oTTFiMGmJvLQ
         FORZLH7o+VPS9ADC9BfhGvm+7d0eczKG6YP79Icqz/E7N6PzOzB2E2HjuYlqJRxkGeUSXcvr7Rvljampd1WY3qo8koDj8w
         lkOGzjOwMRL3kpikhZw285jZ9czu5ExW8wQYr0gERPpqLBcEnaCmwvYokATBkCgYEA1lPCbn8um4e7faqDVYm0H6+2stYU
         HC4ucrmHw3FbvS4ko9omWMj5xyPDUP2x/Ls2AfJSZR9lqPty8yqDTObHiuEPv8q0e0qw+PJIp4kaY8tAFwcIXlphANJIeK
         gAmbfEYyboKzG8Qe+u5gA1gYKFl5zr/WZX0drqM5NG/CZzqfQ=";
         
        System.out.println("Public Key : " + strPublicKey); 
        System.out.println("Private Key : " + strPrivateKey); 
         
        System.out.println("加密前數據:" + src);
         
        //1.公鑰加密
        byte[] keyPublicBytes = Base64.decodeBase64(strPublicKey);
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyPublicBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(src.getBytes());
        System.out.println("公鑰加密、私鑰解密——加密 : " + Base64.encodeBase64String(result));
         
        //2.私鑰解密
        byte[] keyPrivateBytes = Base64.decodeBase64(strPrivateKey);
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyPrivateBytes);
        keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        result = cipher.doFinal(result);
        System.out.println("公鑰加密、私鑰解密——解密:" + new String(result));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

複製代碼

公鑰,私鑰生成工具, 本文代碼適用於 1024, 2048兩種規則生成的密鑰

實例代碼中提供了 公鑰私鑰生成工具

相關文章
相關標籤/搜索