RSA2实例详解

来源:互联网 发布:win10共享网络 编辑:程序博客网 时间:2024/05/29 16:18
本文介绍RSA2加密与解密,RSA2是RSA的加强版本,在密钥长度上采用2048, RSA2比RSA更安全,更可靠, 本人的另一篇文章RSA已经发表,有想了解的可以点开下面的RSA文章, 但RSA2在明文的加密数据长度上有个小缺陷,只能对不超过密文长度的明文进行加密.  
本文附带相关memo:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=357

工具集下载

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

关于RSA2的理论其实与RSA类似,想具体了解的可以参考上面的链接,下面直接上代码


函数test1中使用RSA2的私钥对数据进行加密,使用RSA2的公钥对数据进行解密

下面代码中的密钥字符串是对密钥字节数组进行了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 生成的密文长度总是固定的。

但是明文长度不能超过密钥长度。比如 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两种规则生成的密钥

实例代码中提供了 公钥私钥生成工具



相关demo下载:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=357

原创粉丝点击