文档章节

RSA加密解密实现

hejunbinlan
 hejunbinlan
发布于 2017/07/19 11:55
字数 2343
阅读 31
收藏 0

概述

RSA被称为非对称性加密算法,意思就是加密和解密用的不是同一份密钥。RSA算法的密钥分为公钥和私钥,两者内容不同,用途也不同。公钥用于加密,一般交给客户端使用;私钥用于解密,一般由服务器管理。反过来,对称性加密算法,指的就是用同一份密钥进行加密解密了,比如DES加密算法。

 

RSA算法实现

 

一、生成密钥对

 

在使用RSA加密解密之前,首先要生成密钥对。RSA算法的密钥可以通过两个途径生成,一是借助openssl命令终端,二是使用代码生成。

 

1、Openssl生成密钥对

 

首先你得安装Openssl,这里就不再叙述如何安装Openssl了,正好给你个机会去撩一下度娘。

第一步,生成私钥。现在我们找到openssl安装目录的bin文件夹,双击打开openssl.exe,输入命令

 

[java] view plain copy

  1. genrsa -out rsa_private_key.pem 1024  


 

 

 

 

在openssl.exe的同级目录下可以找到生成的私钥文件rsa_private_key.pem,打开后看到的内容类似下面

 

 

[java] view plain copy

  1. -----BEGIN RSA PRIVATE KEY-----  
  2. MIICWwIBAAKBgQC7yil5BUsHf+PdPl9fzdr3FNyrXDPJwV8Vfk3hCsiqs3YzHYjE  
  3. YpHZiaF8dg9wB/aqmKRA0KFH2eTv++GNf0fAtdfbZUeq1Y79BDs23kSoS6g0Xe8m  
  4. D76A2oD+G0o/llsBjpmWViFaCre0uALyOwd412pU7yj+IJU+JlNlxLapNwIDAQAB  
  5. AoGAH0C+9DgwS3g6WQjXYJ9m8LYVH6PBrrMy+uXBWlGsIdSqOEmTCHQLJ/Qi3w7a  
  6. 9N8uayfqNitCnC2kT1hRKnZjX2Miy0LCfLsH6REV1NUgSmC7lr/TKkq9Hnvp1Y0H  
  7. bi7u5ux6QUzY8Yb7f6go7rAk764EikV8QeuRKsQP0jaPIckCQQDg8yyWlsWL298C  
  8. sn15tQAqmNI8kWpmOmZuvNE0oTzodsMCfi0K3e5c3KtHUgso1hPWTxJguRpWw1jS  
  9. 4NsoYWJTAkEA1bXlP1vHF4DW9XjoE/VSb3ReUXvqCx96IrdxcKXKOPrNsGOpKBkL  
  10. 3x74jImXjIiSEe4ePvOHsQ5HgB9scPlJDQJATcrKuKkbV+qJjN09F0HI9PI0gk2n  
  11. hgLcOZ+CmbjI33typQINgZyOOf72HIv63/xoj8x4hop82VRk+0hXgfdrkQJABQFo  
  12. qC4/IIbNAhzd2rHRR3kDSIdNeQs4sh1307qeXO1K6gm7iYvkoko4ahpC6XC9cxwP  
  13. q0vK7tO1ywNxZ8f+9QJAO2sXpLl4G/I0xrizv9Yoe7MON+8CsMXIUb0Swf3Q4Bbj  
  14. YNWXYD1BBa1qkIQU48dLgbJU24Abzl57nkSN/nns4A==  
  15. -----END RSA PRIVATE KEY-----  


请忽略带有虚线的第一行和最后一行,中间的内容就是我们的私钥了。

 

 

第二步,生成公钥。继续在openssl终端窗口输入命令:

 

[java] view plain copy

  1. rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout    


 

 

这里根据私钥数据,生成了公钥,同样也是保存在openssl.exe同级目录下,打开看里面的内容:

 

 

[java] view plain copy

  1. -----BEGIN PUBLIC KEY-----  
  2. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7yil5BUsHf+PdPl9fzdr3FNyr  
  3. XDPJwV8Vfk3hCsiqs3YzHYjEYpHZiaF8dg9wB/aqmKRA0KFH2eTv++GNf0fAtdfb  
  4. ZUeq1Y79BDs23kSoS6g0Xe8mD76A2oD+G0o/llsBjpmWViFaCre0uALyOwd412pU  
  5. 7yj+IJU+JlNlxLapNwIDAQAB  
  6. -----END PUBLIC KEY-----  


到这里,密钥对基本生成了,但是这个密钥对的私钥无法在代码中直接使用,需要对私钥进行PKCS#8编码,继续敲命令:

 

 

[java] view plain copy

  1. pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt  


 

 

同样在openssl.exe同级目录下找到文件pkcs8_rsa_private_key.pem,这里就是我们最终需要的私钥了。

 

下面可以看到内容跟rsa_private_key.pem里面的内容是不一样的:

 

[java] view plain copy

  1. -----BEGIN PRIVATE KEY-----  
  2. MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALvKKXkFSwd/490+  
  3. X1/N2vcU3KtcM8nBXxV+TeEKyKqzdjMdiMRikdmJoXx2D3AH9qqYpEDQoUfZ5O/7  
  4. 4Y1/R8C119tlR6rVjv0EOzbeRKhLqDRd7yYPvoDagP4bSj+WWwGOmZZWIVoKt7S4  
  5. AvI7B3jXalTvKP4glT4mU2XEtqk3AgMBAAECgYAfQL70ODBLeDpZCNdgn2bwthUf  
  6. o8GuszL65cFaUawh1Ko4SZMIdAsn9CLfDtr03y5rJ+o2K0KcLaRPWFEqdmNfYyLL  
  7. QsJ8uwfpERXU1SBKYLuWv9MqSr0ee+nVjQduLu7m7HpBTNjxhvt/qCjusCTvrgSK  
  8. RXxB65EqxA/SNo8hyQJBAODzLJaWxYvb3wKyfXm1ACqY0jyRamY6Zm680TShPOh2  
  9. wwJ+LQrd7lzcq0dSCyjWE9ZPEmC5GlbDWNLg2yhhYlMCQQDVteU/W8cXgNb1eOgT  
  10. 9VJvdF5Re+oLH3oit3Fwpco4+s2wY6koGQvfHviMiZeMiJIR7h4+84exDkeAH2xw  
  11. +UkNAkBNysq4qRtX6omM3T0XQcj08jSCTaeGAtw5n4KZuMjfe3KlAg2BnI45/vYc  
  12. i/rf/GiPzHiGinzZVGT7SFeB92uRAkAFAWioLj8ghs0CHN3asdFHeQNIh015Cziy  
  13. HXfTup5c7UrqCbuJi+SiSjhqGkLpcL1zHA+rS8ru07XLA3Fnx/71AkA7axekuXgb  
  14. 8jTGuLO/1ih7sw437wKwxchRvRLB/dDgFuNg1ZdgPUEFrWqQhBTjx0uBslTbgBvO  
  15. XnueRI3+eezg  
  16. -----END PRIVATE KEY-----  


 

 

2、代码生成密钥对

除了上面的openssl方法可以生成密钥对外,使用代码也是可以生成的,具体的代码如下:

 

[java] view plain copy

  1. public static KeyPair generateRSAKeyPair(int keyLength)  
  2. {  
  3.     try  
  4.     {  
  5.         KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);  
  6.         kpg.initialize(keyLength);  
  7.         return kpg.genKeyPair();  
  8.     } catch (NoSuchAlgorithmException e)  
  9.     {  
  10.         e.printStackTrace();  
  11.         return null;  
  12.     }  
  13. }  


keyLength范围512~2048,一般取1024,其他值本人没尝试过,有探索精神的可以自行更改。

 

通过keyPair.getPublic().getEncoded(),keyPair.getPrivate().getEncoded()分别获取公钥、私钥的字节码。

为了更直观一点,可以通过Base64编码把字节码转为可读的字符串保存起来 Base64Utils.encode(rsaKeyPair.getPublic().getEncoded());

 

二、RSA加密解密代码实现

 

废话少说,赶着回家吃饭,上代码:

 

 

[java] view plain copy

  1. package com.yspay.sdk.util;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.ByteArrayOutputStream;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7. import java.io.InputStreamReader;  
  8. import java.math.BigInteger;  
  9. import java.security.KeyFactory;  
  10. import java.security.KeyPair;  
  11. import java.security.KeyPairGenerator;  
  12. import java.security.NoSuchAlgorithmException;  
  13. import java.security.PrivateKey;  
  14. import java.security.PublicKey;  
  15. import java.security.interfaces.RSAPrivateKey;  
  16. import java.security.interfaces.RSAPublicKey;  
  17. import java.security.spec.InvalidKeySpecException;  
  18. import java.security.spec.PKCS8EncodedKeySpec;  
  19. import java.security.spec.RSAPublicKeySpec;  
  20. import java.security.spec.X509EncodedKeySpec;  
  21.   
  22. import javax.crypto.Cipher;  
  23.   
  24. /** 
  25.  *  
  26.  */  
  27. public final class RSAUtils  
  28. {  
  29.     private static String RSA = "RSA";  
  30.   
  31.     /** 
  32.      * 随机生成RSA密钥对(默认密钥长度为1024) 
  33.      * 
  34.      * @return 
  35.      */  
  36.     public static KeyPair generateRSAKeyPair()  
  37.     {  
  38.         return generateRSAKeyPair(1024);  
  39.     }  
  40.   
  41.     /** 
  42.      * 随机生成RSA密钥对 
  43.      * 
  44.      * @param keyLength 
  45.      *            密钥长度,范围:512~2048<br> 
  46.      *            一般1024 
  47.      * @return 
  48.      */  
  49.     public static KeyPair generateRSAKeyPair(int keyLength)  
  50.     {  
  51.         try  
  52.         {  
  53.             KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);  
  54.             kpg.initialize(keyLength);  
  55.             return kpg.genKeyPair();  
  56.         } catch (NoSuchAlgorithmException e)  
  57.         {  
  58.             e.printStackTrace();  
  59.             return null;  
  60.         }  
  61.     }  
  62.   
  63.     /** 
  64.      * 用公钥加密 <br> 
  65.      * 每次加密的字节数,不能超过密钥的长度值除以 8 再减去 11,所以采取分段加密的方式规避 
  66.      * 
  67.      * @param data 需加密数据的byte数据 
  68.      * @param publicKey 公钥 
  69.      * @return 加密后的byte型数据 
  70.      */  
  71.     public static byte[] encryptData(byte[] data, PublicKey publicKey)  
  72.     {  
  73.         try  
  74.         {  
  75.             Cipher cipher = Cipher.getInstance(RSA);  
  76.             // 编码前设定编码方式及密钥  
  77.             cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
  78.   
  79.             RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;  
  80.             // 模长  
  81.             int keyLen = rsaPublicKey.getModulus().bitLength() / 8;  
  82.             int maxEncryptBlock = keyLen - 11;  
  83.   
  84.             //如果明文长度大于模长-11则要分组加密  
  85.             int inputLen = data.length;  
  86.             ByteArrayOutputStream out = new ByteArrayOutputStream();  
  87.             int offSet = 0;  
  88.             byte[] temp;  
  89.             int i = 0;  
  90.             // 对数据分段加密  
  91.             while (inputLen - offSet > 0) {  
  92.                 if (inputLen - offSet > maxEncryptBlock) {  
  93.                     temp = cipher.doFinal(data, offSet, maxEncryptBlock);  
  94.                 } else {  
  95.                     temp = cipher.doFinal(data, offSet, inputLen - offSet);  
  96.                 }  
  97.                 out.write(temp, 0, temp.length);  
  98.                 i++;  
  99.                 offSet = i * maxEncryptBlock;  
  100.             }  
  101.             byte[] encryptedData = out.toByteArray();  
  102.             out.close();  
  103.             // 传入编码数据并返回编码结果  
  104.             return encryptedData;  
  105.         } catch (Exception e)  
  106.         {  
  107.             e.printStackTrace();  
  108.             return null;  
  109.         }  
  110.     }  
  111.   
  112.     /** 
  113.      * 用私钥解密 
  114.      * 
  115.      * @param encryptedData 经过encryptedData()加密返回的byte数据 
  116.      * @param privateKey 私钥 
  117.      * @return 
  118.      */  
  119.     public static byte[] decryptData(byte[] encryptedData, PrivateKey privateKey)  
  120.     {  
  121.         try  
  122.         {  
  123.             Cipher cipher = Cipher.getInstance(RSA);  
  124.             cipher.init(Cipher.DECRYPT_MODE, privateKey);  
  125.   
  126.             RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;  
  127.             // 模长  
  128.             int keyLen = rsaPrivateKey.getModulus().bitLength() / 8;  
  129.             int maxDecryptBlock = keyLen;//不用减11  
  130.   
  131.             //如果密文长度大于模长则要分组解密  
  132.             int inputLen = encryptedData.length;  
  133.             ByteArrayOutputStream out = new ByteArrayOutputStream();  
  134.             int offSet = 0;  
  135.             byte[] temp;  
  136.             int i = 0;  
  137.             // 对数据分段解密  
  138.             while (inputLen - offSet > 0) {  
  139.                 if (inputLen - offSet > maxDecryptBlock) {  
  140.                     temp = cipher.doFinal(encryptedData, offSet, maxDecryptBlock);  
  141.                 } else {  
  142.                     temp = cipher.doFinal(encryptedData, offSet, inputLen - offSet);  
  143.                 }  
  144.                 out.write(temp, 0, temp.length);  
  145.                 i++;  
  146.                 offSet = i * maxDecryptBlock;  
  147.             }  
  148.             byte[] decryptedData = out.toByteArray();  
  149.             out.close();  
  150.   
  151.             return decryptedData;  
  152.         } catch (Exception e)  
  153.         {  
  154.             e.printStackTrace();  
  155.             return null;  
  156.         }  
  157.     }  
  158.   
  159.     /** 
  160.      * 通过公钥byte[](publicKey.getEncoded())将公钥还原,适用于RSA算法 
  161.      * 
  162.      * @param keyBytes 
  163.      * @return 
  164.      * @throws NoSuchAlgorithmException 
  165.      * @throws InvalidKeySpecException 
  166.      */  
  167.     public static PublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException,  
  168.             InvalidKeySpecException  
  169.     {  
  170.         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);  
  171.         KeyFactory keyFactory = KeyFactory.getInstance(RSA);  
  172.         PublicKey publicKey = keyFactory.generatePublic(keySpec);  
  173.         return publicKey;  
  174.     }  
  175.   
  176.     /** 
  177.      * 通过私钥byte[]将公钥还原,适用于RSA算法 
  178.      * 
  179.      * @param keyBytes 
  180.      * @return 
  181.      * @throws NoSuchAlgorithmException 
  182.      * @throws InvalidKeySpecException 
  183.      */  
  184.     public static PrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException,  
  185.             InvalidKeySpecException  
  186.     {  
  187.         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);  
  188.         KeyFactory keyFactory = KeyFactory.getInstance(RSA);  
  189.         PrivateKey privateKey = keyFactory.generatePrivate(keySpec);  
  190.         return privateKey;  
  191.     }  
  192.   
  193.     /** 
  194.      * 使用N、e值还原公钥 
  195.      * 
  196.      * @param modulus 
  197.      * @param publicExponent 
  198.      * @return 
  199.      * @throws NoSuchAlgorithmException 
  200.      * @throws InvalidKeySpecException 
  201.      */  
  202.     public static PublicKey getPublicKey(String modulus, String publicExponent)  
  203.             throws NoSuchAlgorithmException, InvalidKeySpecException  
  204.     {  
  205.         BigInteger bigIntModulus = new BigInteger(modulus);  
  206.         BigInteger bigIntPrivateExponent = new BigInteger(publicExponent);  
  207.         RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent);  
  208.         KeyFactory keyFactory = KeyFactory.getInstance(RSA);  
  209.         PublicKey publicKey = keyFactory.generatePublic(keySpec);  
  210.         return publicKey;  
  211.     }  
  212.   
  213.     /** 
  214.      * 使用N、d值还原私钥 
  215.      * 
  216.      * @param modulus 
  217.      * @param privateExponent 
  218.      * @return 
  219.      * @throws NoSuchAlgorithmException 
  220.      * @throws InvalidKeySpecException 
  221.      */  
  222.     public static PrivateKey getPrivateKey(String modulus, String privateExponent)  
  223.             throws NoSuchAlgorithmException, InvalidKeySpecException  
  224.     {  
  225.         BigInteger bigIntModulus = new BigInteger(modulus);  
  226.         BigInteger bigIntPrivateExponent = new BigInteger(privateExponent);  
  227.         RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent);  
  228.         KeyFactory keyFactory = KeyFactory.getInstance(RSA);  
  229.         PrivateKey privateKey = keyFactory.generatePrivate(keySpec);  
  230.         return privateKey;  
  231.     }  
  232.   
  233.     /** 
  234.      * 从字符串中加载公钥 
  235.      * 
  236.      * @param publicKeyStr 
  237.      *            公钥数据字符串 
  238.      * @throws Exception 
  239.      *             加载公钥时产生的异常 
  240.      */  
  241.     public static PublicKey loadPublicKey(String publicKeyStr) throws Exception  
  242.     {  
  243.         try  
  244.         {  
  245.             byte[] buffer = Base64Utils.decode(publicKeyStr);  
  246.             KeyFactory keyFactory = KeyFactory.getInstance(RSA);  
  247.             X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);  
  248.             return (RSAPublicKey) keyFactory.generatePublic(keySpec);  
  249.         } catch (NoSuchAlgorithmException e)  
  250.         {  
  251.             throw new Exception("无此算法");  
  252.         } catch (InvalidKeySpecException e)  
  253.         {  
  254.             throw new Exception("公钥非法");  
  255.         } catch (NullPointerException e)  
  256.         {  
  257.             throw new Exception("公钥数据为空");  
  258.         }  
  259.     }  
  260.   
  261.     /** 
  262.      * 从字符串中加载私钥<br> 
  263.      * 加载时使用的是PKCS8EncodedKeySpec(PKCS#8编码的Key指令)。 
  264.      * 
  265.      * @param privateKeyStr 
  266.      * @return 
  267.      * @throws Exception 
  268.      */  
  269.     public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception  
  270.     {  
  271.         try  
  272.         {  
  273.             byte[] buffer = Base64Utils.decode(privateKeyStr);  
  274.             //X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);  
  275.             PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);  
  276.             KeyFactory keyFactory = KeyFactory.getInstance(RSA);  
  277.             return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);  
  278.         } catch (NoSuchAlgorithmException e)  
  279.         {  
  280.             throw new Exception("无此算法");  
  281.         } catch (InvalidKeySpecException e)  
  282.         {  
  283.             throw new Exception("私钥非法");  
  284.         } catch (NullPointerException e)  
  285.         {  
  286.             throw new Exception("私钥数据为空");  
  287.         }  
  288.     }  
  289.   
  290.     /** 
  291.      * 从文件中输入流中加载公钥 
  292.      * 
  293.      * @param in 
  294.      *            公钥输入流 
  295.      * @throws Exception 
  296.      *             加载公钥时产生的异常 
  297.      */  
  298.     public static PublicKey loadPublicKey(InputStream in) throws Exception  
  299.     {  
  300.         try  
  301.         {  
  302.             return loadPublicKey(readKey(in));  
  303.         } catch (IOException e)  
  304.         {  
  305.             throw new Exception("公钥数据流读取错误");  
  306.         } catch (NullPointerException e)  
  307.         {  
  308.             throw new Exception("公钥输入流为空");  
  309.         }  
  310.     }  
  311.   
  312.     /** 
  313.      * 从文件中加载私钥 
  314.      * @param in 
  315.      * @return 私钥 
  316.      * @throws Exception 
  317.      */  
  318.     public static PrivateKey loadPrivateKey(InputStream in) throws Exception  
  319.     {  
  320.         try  
  321.         {  
  322.             return loadPrivateKey(readKey(in));  
  323.         } catch (IOException e)  
  324.         {  
  325.             throw new Exception("私钥数据读取错误");  
  326.         } catch (NullPointerException e)  
  327.         {  
  328.             throw new Exception("私钥输入流为空");  
  329.         }  
  330.     }  
  331.   
  332.     /** 
  333.      * 读取密钥信息 
  334.      * 
  335.      * @param in 
  336.      * @return 
  337.      * @throws IOException 
  338.      */  
  339.     private static String readKey(InputStream in) throws IOException  
  340.     {  
  341.         BufferedReader br = new BufferedReader(new InputStreamReader(in));  
  342.         String readLine = null;  
  343.         StringBuilder sb = new StringBuilder();  
  344.         while ((readLine = br.readLine()) != null)  
  345.         {  
  346.             if (readLine.charAt(0) == '-')  
  347.             {  
  348.                 continue;  
  349.             } else  
  350.             {  
  351.                 sb.append(readLine);  
  352.                 sb.append('\r');  
  353.             }  
  354.         }  
  355.   
  356.         return sb.toString();  
  357.     }  
  358.   
  359. }  


Base64编码工具可以使用系统自带的android.util.Base64,也可以自己实现,以下是 从别处扣来的代码:

 

 

 

[java] view plain copy

  1. package com.yspay.sdk.util;  
  2.   
  3. import java.io.UnsupportedEncodingException;  
  4.   
  5. /** 
  6.  * Created by MPC on 2017/5/24. 
  7.  */  
  8.   
  9. public class Base64Utils {  
  10.   
  11.     private static char[] base64EncodeChars = new char[]  
  12.             { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',  
  13.                     'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',  
  14.                     'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',  
  15.                     '6', '7', '8', '9', '+', '/' };  
  16.     private static byte[] base64DecodeChars = new byte[]  
  17.             { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  18.                     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53,  
  19.                     54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,  
  20.                     12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29,  
  21.                     30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1,  
  22.                     -1, -1, -1 };  
  23.   
  24.     /** 
  25.      * 加密 
  26.      * 
  27.      * @param data 
  28.      * @return 
  29.      */  
  30.     public static String encode(byte[] data)  
  31.     {  
  32.         StringBuffer sb = new StringBuffer();  
  33.         int len = data.length;  
  34.         int i = 0;  
  35.         int b1, b2, b3;  
  36.         while (i < len)  
  37.         {  
  38.             b1 = data[i++] & 0xff;  
  39.             if (i == len)  
  40.             {  
  41.                 sb.append(base64EncodeChars[b1 >>> 2]);  
  42.                 sb.append(base64EncodeChars[(b1 & 0x3) << 4]);  
  43.                 sb.append("==");  
  44.                 break;  
  45.             }  
  46.             b2 = data[i++] & 0xff;  
  47.             if (i == len)  
  48.             {  
  49.                 sb.append(base64EncodeChars[b1 >>> 2]);  
  50.                 sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);  
  51.                 sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);  
  52.                 sb.append("=");  
  53.                 break;  
  54.             }  
  55.             b3 = data[i++] & 0xff;  
  56.             sb.append(base64EncodeChars[b1 >>> 2]);  
  57.             sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);  
  58.             sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);  
  59.             sb.append(base64EncodeChars[b3 & 0x3f]);  
  60.         }  
  61.         return sb.toString();  
  62.     }  
  63.   
  64.     /** 
  65.      * 解密 
  66.      * 
  67.      * @param str 
  68.      * @return 
  69.      */  
  70.     public static byte[] decode(String str)  
  71.     {  
  72.         try  
  73.         {  
  74.             return decodePrivate(str);  
  75.         } catch (UnsupportedEncodingException e)  
  76.         {  
  77.             e.printStackTrace();  
  78.         }  
  79.         return new byte[]  
  80.                 {};  
  81.     }  
  82.   
  83.     private static byte[] decodePrivate(String str) throws UnsupportedEncodingException  
  84.     {  
  85.         StringBuffer sb = new StringBuffer();  
  86.         byte[] data = null;  
  87.         data = str.getBytes("US-ASCII");  
  88.         int len = data.length;  
  89.         int i = 0;  
  90.         int b1, b2, b3, b4;  
  91.         while (i < len)  
  92.         {  
  93.   
  94.             do  
  95.             {  
  96.                 b1 = base64DecodeChars[data[i++]];  
  97.             } while (i < len && b1 == -1);  
  98.             if (b1 == -1)  
  99.                 break;  
  100.   
  101.             do  
  102.             {  
  103.                 b2 = base64DecodeChars[data[i++]];  
  104.             } while (i < len && b2 == -1);  
  105.             if (b2 == -1)  
  106.                 break;  
  107.             sb.append((char) ((b1 << 2) | ((b2 & 0x30) >>> 4)));  
  108.   
  109.             do  
  110.             {  
  111.                 b3 = data[i++];  
  112.                 if (b3 == 61)  
  113.                     return sb.toString().getBytes("iso8859-1");  
  114.                 b3 = base64DecodeChars[b3];  
  115.             } while (i < len && b3 == -1);  
  116.             if (b3 == -1)  
  117.                 break;  
  118.             sb.append((char) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2)));  
  119.   
  120.             do  
  121.             {  
  122.                 b4 = data[i++];  
  123.                 if (b4 == 61)  
  124.                     return sb.toString().getBytes("iso8859-1");  
  125.                 b4 = base64DecodeChars[b4];  
  126.             } while (i < len && b4 == -1);  
  127.             if (b4 == -1)  
  128.                 break;  
  129.             sb.append((char) (((b3 & 0x03) << 6) | b4));  
  130.         }  
  131.         return sb.toString().getBytes("iso8859-1");  
  132.     }  
  133. }  

 

 

最后附上工程代码,此处传送门:点击打开链接

 

工程界面如下:

 

本文转载自:http://blog.csdn.net/hustpzb/article/details/72734578

hejunbinlan
粉丝 41
博文 596
码字总数 21569
作品 0
浦东
高级程序员
私信 提问
javax.crypto.BadPaddingException: Blocktype mis...

错误:javax.crypto.BadPaddingException: Blocktype mismatch 1.最近做RSA加密用于增强android客户机与服务器(JavaEE)数据传输的安全性。发现在andorid上生成的(密钥对由服务器在windows下...

cwalet
2011/11/23
5K
3
RSA加密解密及数字签名Java实现

RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三...

Jialy
2013/10/25
36.4K
5
RSA加解密及签名算法的技术原理及其Go语言实现

  对称加密中,加密和解密使用相同的密钥,因此必须向解密者配送密钥,即密钥配送问题。而非对称加密中,由于加密和解密分别使用公钥和私钥,而公钥是公开的,因此可以规避密钥配送问题。非...

莫名2013
2018/01/04
0
0
浅谈android数据存储加密

写在开头 CSDN:http://blog.csdn.net/sayfromwen 掘金:https://juejin.im/user/59b09eb2518825241e2255ea 在移动端的开发中,数据安全的问题一直是大家备受关注的,数据加密技术也受到了大...

亭子happy
2018/10/15
31
0
浅析RSA公钥密码以及使用Java自带API实现RSA的密钥生成和加解密

RSA是目前最流行的非对称密码,目前广泛应用在数字签名,数字证书上。 那么什么是非对称密码呢?就是给明文加密的密钥和给密文解密的密钥是不一样的。其中,对外暴露的是公钥,自己保留的是私...

Lunqi
2015/07/15
1K
1

没有更多内容

加载失败,请刷新页面

加载更多

Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程。 一、ThreadPoolTaskExecutor 本文采用 Executors 的工厂...

CREATE_17
今天
5
0
CSS盒子模型

CSS盒子模型 组成: content --> padding --> border --> margin 像现实生活中的快递: 物品 --> 填充物 --> 包装盒 --> 盒子与盒子之间的间距 content :width、height组成的 内容区域 padd......

studywin
今天
7
0
修复Win10下开始菜单、设置等系统软件无法打开的问题

因为各种各样的原因导致系统文件丢失、损坏、被修改,而造成win10的开始菜单、设置等系统软件无法打开的情况,可以尝试如下方法解决 此方法只在部分情况下有效,但值得一试 用Windows键+R打开...

locbytes
昨天
8
0
jquery 添加和删除节点

本文转载于:专业的前端网站➺jquery 添加和删除节点 // 增加一个三和一节点function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(".triple-panel-con......

前端老手
昨天
8
0
一、Django基础

一、web框架分类和wsgiref模块使用介绍 web框架的本质 socket服务端 与 浏览器的通信 socket服务端功能划分: 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn... 根据用户访问...

ZeroBit
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部