Java使用RSA加密解密签名及校验

由于项目要用到非对称加密解密签名校验什么的,于是参考《Java加密解密的艺术》写一个RSA进行加密解密签名及校验的Demo,代码很简单,特此分享!

RSA加密解密类:

  1. package com.ihep;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.BufferedWriter;  
  5. import java.io.FileReader;  
  6. import java.io.FileWriter;  
  7. import java.io.IOException;  
  8. import java.security.InvalidKeyException;  
  9. import java.security.KeyFactory;  
  10. import java.security.KeyPair;  
  11. import java.security.KeyPairGenerator;  
  12. import java.security.NoSuchAlgorithmException;  
  13. import java.security.SecureRandom;  
  14.   
  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.X509EncodedKeySpec;  
  20.   
  21. import javax.crypto.BadPaddingException;  
  22. import javax.crypto.Cipher;  
  23. import javax.crypto.IllegalBlockSizeException;  
  24. import javax.crypto.NoSuchPaddingException;  
  25.   
  26. import com.fcplay.Base64;  
  27.   
  28. public class RSAEncrypt {  
  29.     /** 
  30.      * 字节数据转字符串专用集合 
  31.      */  
  32.     private static final char[] HEX_CHAR = { '0''1''2''3''4''5''6',  
  33.             '7''8''9''a''b''c''d''e''f' };  
  34.   
  35.     /** 
  36.      * 随机生成密钥对 
  37.      */  
  38.     public static void genKeyPair(String filePath) {  
  39.         // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象  
  40.         KeyPairGenerator keyPairGen = null;  
  41.         try {  
  42.             keyPairGen = KeyPairGenerator.getInstance("RSA");  
  43.         } catch (NoSuchAlgorithmException e) {  
  44.             // TODO Auto-generated catch block  
  45.             e.printStackTrace();  
  46.         }  
  47.         // 初始化密钥对生成器,密钥大小为96-1024位  
  48.         keyPairGen.initialize(1024,new SecureRandom());  
  49.         // 生成一个密钥对,保存在keyPair中  
  50.         KeyPair keyPair = keyPairGen.generateKeyPair();  
  51.         // 得到私钥  
  52.         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  
  53.         // 得到公钥  
  54.         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  
  55.         try {  
  56.             // 得到公钥字符串  
  57.             String publicKeyString = Base64.encode(publicKey.getEncoded());  
  58.             // 得到私钥字符串  
  59.             String privateKeyString = Base64.encode(privateKey.getEncoded());  
  60.             // 将密钥对写入到文件  
  61.             FileWriter pubfw = new FileWriter(filePath + "/publicKey.keystore");  
  62.             FileWriter prifw = new FileWriter(filePath + "/privateKey.keystore");  
  63.             BufferedWriter pubbw = new BufferedWriter(pubfw);  
  64.             BufferedWriter pribw = new BufferedWriter(prifw);  
  65.             pubbw.write(publicKeyString);  
  66.             pribw.write(privateKeyString);  
  67.             pubbw.flush();  
  68.             pubbw.close();  
  69.             pubfw.close();  
  70.             pribw.flush();  
  71.             pribw.close();  
  72.             prifw.close();  
  73.         } catch (Exception e) {  
  74.             e.printStackTrace();  
  75.         }  
  76.     }  
  77.   
  78.     /** 
  79.      * 从文件中输入流中加载公钥 
  80.      *  
  81.      * @param in 
  82.      *            公钥输入流 
  83.      * @throws Exception 
  84.      *             加载公钥时产生的异常 
  85.      */  
  86.     public static String loadPublicKeyByFile(String path) throws Exception {  
  87.         try {  
  88.             BufferedReader br = new BufferedReader(new FileReader(path  
  89.                     + "/publicKey.keystore"));  
  90.             String readLine = null;  
  91.             StringBuilder sb = new StringBuilder();  
  92.             while ((readLine = br.readLine()) != null) {  
  93.                 sb.append(readLine);  
  94.             }  
  95.             br.close();  
  96.             return sb.toString();  
  97.         } catch (IOException e) {  
  98.             throw new Exception("公钥数据流读取错误");  
  99.         } catch (NullPointerException e) {  
  100.             throw new Exception("公钥输入流为空");  
  101.         }  
  102.     }  
  103.   
  104.     /** 
  105.      * 从字符串中加载公钥 
  106.      *  
  107.      * @param publicKeyStr 
  108.      *            公钥数据字符串 
  109.      * @throws Exception 
  110.      *             加载公钥时产生的异常 
  111.      */  
  112.     public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr)  
  113.             throws Exception {  
  114.         try {  
  115.             byte[] buffer = Base64.decode(publicKeyStr);  
  116.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  117.             X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);  
  118.             return (RSAPublicKey) keyFactory.generatePublic(keySpec);  
  119.         } catch (NoSuchAlgorithmException e) {  
  120.             throw new Exception("无此算法");  
  121.         } catch (InvalidKeySpecException e) {  
  122.             throw new Exception("公钥非法");  
  123.         } catch (NullPointerException e) {  
  124.             throw new Exception("公钥数据为空");  
  125.         }  
  126.     }  
  127.   
  128.     /** 
  129.      * 从文件中加载私钥 
  130.      *  
  131.      * @param keyFileName 
  132.      *            私钥文件名 
  133.      * @return 是否成功 
  134.      * @throws Exception 
  135.      */  
  136.     public static String loadPrivateKeyByFile(String path) throws Exception {  
  137.         try {  
  138.             BufferedReader br = new BufferedReader(new FileReader(path  
  139.                     + "/privateKey.keystore"));  
  140.             String readLine = null;  
  141.             StringBuilder sb = new StringBuilder();  
  142.             while ((readLine = br.readLine()) != null) {  
  143.                 sb.append(readLine);  
  144.             }  
  145.             br.close();  
  146.             return sb.toString();  
  147.         } catch (IOException e) {  
  148.             throw new Exception("私钥数据读取错误");  
  149.         } catch (NullPointerException e) {  
  150.             throw new Exception("私钥输入流为空");  
  151.         }  
  152.     }  
  153.   
  154.     public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr)  
  155.             throws Exception {  
  156.         try {  
  157.             byte[] buffer = Base64.decode(privateKeyStr);  
  158.             PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);  
  159.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  160.             return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);  
  161.         } catch (NoSuchAlgorithmException e) {  
  162.             throw new Exception("无此算法");  
  163.         } catch (InvalidKeySpecException e) {  
  164.             throw new Exception("私钥非法");  
  165.         } catch (NullPointerException e) {  
  166.             throw new Exception("私钥数据为空");  
  167.         }  
  168.     }  
  169.   
  170.     /** 
  171.      * 公钥加密过程 
  172.      *  
  173.      * @param publicKey 
  174.      *            公钥 
  175.      * @param plainTextData 
  176.      *            明文数据 
  177.      * @return 
  178.      * @throws Exception 
  179.      *             加密过程中的异常信息 
  180.      */  
  181.     public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData)  
  182.             throws Exception {  
  183.         if (publicKey == null) {  
  184.             throw new Exception("加密公钥为空, 请设置");  
  185.         }  
  186.         Cipher cipher = null;  
  187.         try {  
  188.             // 使用默认RSA  
  189.             cipher = Cipher.getInstance("RSA");  
  190.             // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());  
  191.             cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
  192.             byte[] output = cipher.doFinal(plainTextData);  
  193.             return output;  
  194.         } catch (NoSuchAlgorithmException e) {  
  195.             throw new Exception("无此加密算法");  
  196.         } catch (NoSuchPaddingException e) {  
  197.             e.printStackTrace();  
  198.             return null;  
  199.         } catch (InvalidKeyException e) {  
  200.             throw new Exception("加密公钥非法,请检查");  
  201.         } catch (IllegalBlockSizeException e) {  
  202.             throw new Exception("明文长度非法");  
  203.         } catch (BadPaddingException e) {  
  204.             throw new Exception("明文数据已损坏");  
  205.         }  
  206.     }  
  207.   
  208.     /** 
  209.      * 私钥加密过程 
  210.      *  
  211.      * @param privateKey 
  212.      *            私钥 
  213.      * @param plainTextData 
  214.      *            明文数据 
  215.      * @return 
  216.      * @throws Exception 
  217.      *             加密过程中的异常信息 
  218.      */  
  219.     public static byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData)  
  220.             throws Exception {  
  221.         if (privateKey == null) {  
  222.             throw new Exception("加密私钥为空, 请设置");  
  223.         }  
  224.         Cipher cipher = null;  
  225.         try {  
  226.             // 使用默认RSA  
  227.             cipher = Cipher.getInstance("RSA");  
  228.             cipher.init(Cipher.ENCRYPT_MODE, privateKey);  
  229.             byte[] output = cipher.doFinal(plainTextData);  
  230.             return output;  
  231.         } catch (NoSuchAlgorithmException e) {  
  232.             throw new Exception("无此加密算法");  
  233.         } catch (NoSuchPaddingException e) {  
  234.             e.printStackTrace();  
  235.             return null;  
  236.         } catch (InvalidKeyException e) {  
  237.             throw new Exception("加密私钥非法,请检查");  
  238.         } catch (IllegalBlockSizeException e) {  
  239.             throw new Exception("明文长度非法");  
  240.         } catch (BadPaddingException e) {  
  241.             throw new Exception("明文数据已损坏");  
  242.         }  
  243.     }  
  244.   
  245.     /** 
  246.      * 私钥解密过程 
  247.      *  
  248.      * @param privateKey 
  249.      *            私钥 
  250.      * @param cipherData 
  251.      *            密文数据 
  252.      * @return 明文 
  253.      * @throws Exception 
  254.      *             解密过程中的异常信息 
  255.      */  
  256.     public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)  
  257.             throws Exception {  
  258.         if (privateKey == null) {  
  259.             throw new Exception("解密私钥为空, 请设置");  
  260.         }  
  261.         Cipher cipher = null;  
  262.         try {  
  263.             // 使用默认RSA  
  264.             cipher = Cipher.getInstance("RSA");  
  265.             // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());  
  266.             cipher.init(Cipher.DECRYPT_MODE, privateKey);  
  267.             byte[] output = cipher.doFinal(cipherData);  
  268.             return output;  
  269.         } catch (NoSuchAlgorithmException e) {  
  270.             throw new Exception("无此解密算法");  
  271.         } catch (NoSuchPaddingException e) {  
  272.             e.printStackTrace();  
  273.             return null;  
  274.         } catch (InvalidKeyException e) {  
  275.             throw new Exception("解密私钥非法,请检查");  
  276.         } catch (IllegalBlockSizeException e) {  
  277.             throw new Exception("密文长度非法");  
  278.         } catch (BadPaddingException e) {  
  279.             throw new Exception("密文数据已损坏");  
  280.         }  
  281.     }  
  282.   
  283.     /** 
  284.      * 公钥解密过程 
  285.      *  
  286.      * @param publicKey 
  287.      *            公钥 
  288.      * @param cipherData 
  289.      *            密文数据 
  290.      * @return 明文 
  291.      * @throws Exception 
  292.      *             解密过程中的异常信息 
  293.      */  
  294.     public static byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData)  
  295.             throws Exception {  
  296.         if (publicKey == null) {  
  297.             throw new Exception("解密公钥为空, 请设置");  
  298.         }  
  299.         Cipher cipher = null;  
  300.         try {  
  301.             // 使用默认RSA  
  302.             cipher = Cipher.getInstance("RSA");  
  303.             // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());  
  304.             cipher.init(Cipher.DECRYPT_MODE, publicKey);  
  305.             byte[] output = cipher.doFinal(cipherData);  
  306.             return output;  
  307.         } catch (NoSuchAlgorithmException e) {  
  308.             throw new Exception("无此解密算法");  
  309.         } catch (NoSuchPaddingException e) {  
  310.             e.printStackTrace();  
  311.             return null;  
  312.         } catch (InvalidKeyException e) {  
  313.             throw new Exception("解密公钥非法,请检查");  
  314.         } catch (IllegalBlockSizeException e) {  
  315.             throw new Exception("密文长度非法");  
  316.         } catch (BadPaddingException e) {  
  317.             throw new Exception("密文数据已损坏");  
  318.         }  
  319.     }  
  320.   
  321.     /** 
  322.      * 字节数据转十六进制字符串 
  323.      *  
  324.      * @param data 
  325.      *            输入数据 
  326.      * @return 十六进制内容 
  327.      */  
  328.     public static String byteArrayToString(byte[] data) {  
  329.         StringBuilder stringBuilder = new StringBuilder();  
  330.         for (int i = 0; i < data.length; i++) {  
  331.             // 取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移  
  332.             stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);  
  333.             // 取出字节的低四位 作为索引得到相应的十六进制标识符  
  334.             stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);  
  335.             if (i < data.length - 1) {  
  336.                 stringBuilder.append(' ');  
  337.             }  
  338.         }  
  339.         return stringBuilder.toString();  
  340.     }  
  341. }  

签名及校验类:

  1. package com.ihep;  
  2.   
  3. import java.security.KeyFactory;  
  4. import java.security.PrivateKey;  
  5. import java.security.PublicKey;  
  6. import java.security.spec.PKCS8EncodedKeySpec;  
  7. import java.security.spec.X509EncodedKeySpec;  
  8.   
  9.   
  10.   
  11. / 
  12.   RSA签名验签类 
  13.  /  
  14. public class RSASignature{  
  15.       
  16.     / 
  17.       签名算法 
  18.      /  
  19.     public static final String SIGN_ALGORITHMS = "SHA1WithRSA";  
  20.   
  21.     / 
  22.      RSA签名 
  23.      @param content 待签名数据 
  24.      @param privateKey 商户私钥 
  25.      @param encode 字符集编码 
  26.      @return 签名值 
  27.     /  
  28.     public static String sign(String content, String privateKey, String encode)  
  29.     {  
  30.         try   
  31.         {  
  32.             PKCS8EncodedKeySpec priPKCS8    = new PKCS8EncodedKeySpec( Base64.decode(privateKey) );   
  33.               
  34.             KeyFactory keyf                 = KeyFactory.getInstance("RSA");  
  35.             PrivateKey priKey               = keyf.generatePrivate(priPKCS8);  
  36.   
  37.             java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);  
  38.   
  39.             signature.initSign(priKey);  
  40.             signature.update( content.getBytes(encode));  
  41.   
  42.             byte[] signed = signature.sign();  
  43.               
  44.             return Base64.encode(signed);  
  45.         }  
  46.         catch (Exception e)   
  47.         {  
  48.             e.printStackTrace();  
  49.         }  
  50.           
  51.         return null;  
  52.     }  
  53.       
  54.     public static String sign(String content, String privateKey)  
  55.     {  
  56.         try   
  57.         {  
  58.             PKCS8EncodedKeySpec priPKCS8    = new PKCS8EncodedKeySpec( Base64.decode(privateKey) );   
  59.             KeyFactory keyf = KeyFactory.getInstance("RSA");  
  60.             PrivateKey priKey = keyf.generatePrivate(priPKCS8);  
  61.             java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);  
  62.             signature.initSign(priKey);  
  63.             signature.update( content.getBytes());  
  64.             byte[] signed = signature.sign();  
  65.             return Base64.encode(signed);  
  66.         }  
  67.         catch (Exception e)   
  68.         {  
  69.             e.printStackTrace();  
  70.         }  
  71.         return null;  
  72.     }  
  73.       
  74.     / 
  75.      RSA验签名检查 
  76.      @param content 待签名数据 
  77.      @param sign 签名值 
  78.      @param publicKey 分配给开发商公钥 
  79.      @param encode 字符集编码 
  80.      @return 布尔值 
  81.     */  
  82.     public static boolean doCheck(String content, String sign, String publicKey,String encode)  
  83.     {  
  84.         try   
  85.         {  
  86.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  87.             byte[] encodedKey = Base64.decode(publicKey);  
  88.             PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));  
  89.   
  90.           
  91.             java.security.Signature signature = java.security.Signature  
  92.             .getInstance(SIGN_ALGORITHMS);  
  93.           
  94.             signature.initVerify(pubKey);  
  95.             signature.update( content.getBytes(encode) );  
  96.           
  97.             boolean bverify = signature.verify( Base64.decode(sign) );  
  98.             return bverify;  
  99.               
  100.         }   
  101.         catch (Exception e)   
  102.         {  
  103.             e.printStackTrace();  
  104.         }  
  105.           
  106.         return false;  
  107.     }  
  108.       
  109.     public static boolean doCheck(String content, String sign, String publicKey)  
  110.     {  
  111.         try   
  112.         {  
  113.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  114.             byte[] encodedKey = Base64.decode(publicKey);  
  115.             PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));  
  116.   
  117.           
  118.             java.security.Signature signature = java.security.Signature  
  119.             .getInstance(SIGN_ALGORITHMS);  
  120.           
  121.             signature.initVerify(pubKey);  
  122.             signature.update( content.getBytes() );  
  123.           
  124.             boolean bverify = signature.verify( Base64.decode(sign) );  
  125.             return bverify;  
  126.               
  127.         }   
  128.         catch (Exception e)   
  129.         {  
  130.             e.printStackTrace();  
  131.         }  
  132.           
  133.         return false;  
  134.     }  
  135.       
  136. }  

再来一个Base64的类,当然你也可以用commons-codec-1.9.jar

  1. package com.ihep;  
  2.   
  3. public final class Base64 {  
  4.   
  5.     static private final int     BASELENGTH           = 128;  
  6.     static private final int     LOOKUPLENGTH         = 64;  
  7.     static private final int     TWENTYFOURBITGROUP   = 24;  
  8.     static private final int     EIGHTBIT             = 8;  
  9.     static private final int     SIXTEENBIT           = 16;  
  10.     static private final int     FOURBYTE             = 4;  
  11.     static private final int     SIGN                 = -128;  
  12.     static private final char    PAD                  = '=';  
  13.     static private final boolean fDebug               = false;  
  14.     static final private byte[]  base64Alphabet       = new byte[BASELENGTH];  
  15.     static final private char[]  lookUpBase64Alphabet = new char[LOOKUPLENGTH];  
  16.   
  17.     static {  
  18.         for (int i = 0; i < BASELENGTH; ++i) {  
  19.             base64Alphabet[i] = -1;  
  20.         }  
  21.         for (int i = 'Z'; i >= 'A'; i--) {  
  22.             base64Alphabet[i] = (byte) (i - 'A');  
  23.         }  
  24.         for (int i = 'z'; i >= 'a'; i--) {  
  25.             base64Alphabet[i] = (byte) (i - 'a' + 26);  
  26.         }  
  27.   
  28.         for (int i = '9'; i >= '0'; i--) {  
  29.             base64Alphabet[i] = (byte) (i - '0' + 52);  
  30.         }  
  31.   
  32.         base64Alphabet['+'] = 62;  
  33.         base64Alphabet['/'] = 63;  
  34.   
  35.         for (int i = 0; i <= 25; i++) {  
  36.             lookUpBase64Alphabet[i] = (char) ('A' + i);  
  37.         }  
  38.   
  39.         for (int i = 26, j = 0; i <= 51; i++, j++) {  
  40.             lookUpBase64Alphabet[i] = (char) ('a' + j);  
  41.         }  
  42.   
  43.         for (int i = 52, j = 0; i <= 61; i++, j++) {  
  44.             lookUpBase64Alphabet[i] = (char) ('0' + j);  
  45.         }  
  46.         lookUpBase64Alphabet[62] = (char'+';  
  47.         lookUpBase64Alphabet[63] = (char'/';  
  48.   
  49.     }  
  50.   
  51.     private static boolean isWhiteSpace(char octect) {  
  52.         return (octect  0x20 || octect  0xd || octect  0xa || octect  0x9);  
  53.     }  
  54.   
  55.     private static boolean isPad(char octect) {  
  56.         return (octect  PAD);  
  57.     }  
  58.   
  59.     private static boolean isData(char octect) {  
  60.         return (octect < BASELENGTH && base64Alphabet[octect] != -1);  
  61.     }  
  62.   
  63.     /** 
  64.       Encodes hex octects into Base64 
  65.       
  66.       @param binaryData Array containing binaryData 
  67.       @return Encoded Base64 array 
  68.      */  
  69.     public static String encode(byte[] binaryData) {  
  70.   
  71.         if (binaryData  null) {  
  72.             return null;  
  73.         }  
  74.   
  75.         int lengthDataBits = binaryData.length  EIGHTBIT;  
  76.         if (lengthDataBits == 0) {  
  77.             return "";  
  78.         }  
  79.   
  80.         int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;  
  81.         int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;  
  82.         int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;  
  83.         char encodedData[] = null;  
  84.   
  85.         encodedData = new char[numberQuartet  4];  
  86.   
  87.         byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;  
  88.   
  89.         int encodedIndex = 0;  
  90.         int dataIndex = 0;  
  91.         if (fDebug) {  
  92.             System.out.println("number of triplets = " + numberTriplets);  
  93.         }  
  94.   
  95.         for (int i = 0; i < numberTriplets; i++) {  
  96.             b1 = binaryData[dataIndex++];  
  97.             b2 = binaryData[dataIndex++];  
  98.             b3 = binaryData[dataIndex++];  
  99.   
  100.             if (fDebug) {  
  101.                 System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);  
  102.             }  
  103.   
  104.             l = (byte) (b2 & 0x0f);  
  105.             k = (byte) (b1 & 0x03);  
  106.   
  107.             byte val1 = ((b1 & SIGN)  0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);  
  108.             byte val2 = ((b2 & SIGN)  0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);  
  109.             byte val3 = ((b3 & SIGN)  0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);  
  110.   
  111.             if (fDebug) {  
  112.                 System.out.println("val2 = " + val2);  
  113.                 System.out.println("k4   = " + (k << 4));  
  114.                 System.out.println("vak  = " + (val2 | (k << 4)));  
  115.             }  
  116.   
  117.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];  
  118.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];  
  119.             encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];  
  120.             encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];  
  121.         }  
  122.   
  123.         // form integral number of 6-bit groups  
  124.         if (fewerThan24bits  EIGHTBIT) {  
  125.             b1 = binaryData[dataIndex];  
  126.             k = (byte) (b1 & 0x03);  
  127.             if (fDebug) {  
  128.                 System.out.println("b1=" + b1);  
  129.                 System.out.println("b1<<2 = " + (b1 >> 2));  
  130.             }  
  131.             byte val1 = ((b1 & SIGN)  0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);  
  132.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];  
  133.             encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];  
  134.             encodedData[encodedIndex++] = PAD;  
  135.             encodedData[encodedIndex++] = PAD;  
  136.         } else if (fewerThan24bits  SIXTEENBIT) {  
  137.             b1 = binaryData[dataIndex];  
  138.             b2 = binaryData[dataIndex + 1];  
  139.             l = (byte) (b2 & 0x0f);  
  140.             k = (byte) (b1 & 0x03);  
  141.   
  142.             byte val1 = ((b1 & SIGN)  0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);  
  143.             byte val2 = ((b2 & SIGN)  0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);  
  144.   
  145.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];  
  146.             encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];  
  147.             encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];  
  148.             encodedData[encodedIndex++] = PAD;  
  149.         }  
  150.   
  151.         return new String(encodedData);  
  152.     }  
  153.   
  154.     / 
  155.       Decodes Base64 data into octects 
  156.       
  157.       @param encoded string containing Base64 data 
  158.       @return Array containind decoded data. 
  159.      /  
  160.     public static byte[] decode(String encoded) {  
  161.   
  162.         if (encoded  null) {  
  163.             return null;  
  164.         }  
  165.   
  166.         char[] base64Data = encoded.toCharArray();  
  167.         // remove white spaces  
  168.         int len = removeWhiteSpace(base64Data);  
  169.   
  170.         if (len % FOURBYTE != 0) {  
  171.             return null;//should be divisible by four  
  172.         }  
  173.   
  174.         int numberQuadruple = (len / FOURBYTE);  
  175.   
  176.         if (numberQuadruple  0) {  
  177.             return new byte[0];  
  178.         }  
  179.   
  180.         byte decodedData[] = null;  
  181.         byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;  
  182.         char d1 = 0, d2 = 0, d3 = 0, d4 = 0;  
  183.   
  184.         int i = 0;  
  185.         int encodedIndex = 0;  
  186.         int dataIndex = 0;  
  187.         decodedData = new byte[(numberQuadruple)  3];  
  188.   
  189.         for (; i < numberQuadruple - 1; i++) {  
  190.   
  191.             if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))  
  192.                 || !isData((d3 = base64Data[dataIndex++]))  
  193.                 || !isData((d4 = base64Data[dataIndex++]))) {  
  194.                 return null;  
  195.             }//if found "no data" just return null  
  196.   
  197.             b1 = base64Alphabet[d1];  
  198.             b2 = base64Alphabet[d2];  
  199.             b3 = base64Alphabet[d3];  
  200.             b4 = base64Alphabet[d4];  
  201.   
  202.             decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);  
  203.             decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));  
  204.             decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);  
  205.         }  
  206.   
  207.         if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {  
  208.             return null;//if found "no data" just return null  
  209.         }  
  210.   
  211.         b1 = base64Alphabet[d1];  
  212.         b2 = base64Alphabet[d2];  
  213.   
  214.         d3 = base64Data[dataIndex++];  
  215.         d4 = base64Data[dataIndex++];  
  216.         if (!isData((d3)) || !isData((d4))) {//Check if they are PAD characters  
  217.             if (isPad(d3) && isPad(d4)) {  
  218.                 if ((b2 & 0xf) != 0)//last 4 bits should be zero  
  219.                 {  
  220.                     return null;  
  221.                 }  
  222.                 byte[] tmp = new byte[i  3 + 1];  
  223.                 System.arraycopy(decodedData, 0, tmp, 0, i  3);  
  224.                 tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);  
  225.                 return tmp;  
  226.             } else if (!isPad(d3) && isPad(d4)) {  
  227.                 b3 = base64Alphabet[d3];  
  228.                 if ((b3 & 0x3) != 0)//last 2 bits should be zero  
  229.                 {  
  230.                     return null;  
  231.                 }  
  232.                 byte[] tmp = new byte[i  3 + 2];  
  233.                 System.arraycopy(decodedData, 0, tmp, 0, i  3);  
  234.                 tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);  
  235.                 tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));  
  236.                 return tmp;  
  237.             } else {  
  238.                 return null;  
  239.             }  
  240.         } else { //No PAD e.g 3cQl  
  241.             b3 = base64Alphabet[d3];  
  242.             b4 = base64Alphabet[d4];  
  243.             decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);  
  244.             decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));  
  245.             decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);  
  246.   
  247.         }  
  248.   
  249.         return decodedData;  
  250.     }  
  251.   
  252.     / 
  253.       remove WhiteSpace from MIME containing encoded Base64 data. 
  254.       
  255.       @param data  the byte array of base64 data (with WS) 
  256.       @return      the new length 
  257.      */  
  258.     private static int removeWhiteSpace(char[] data) {  
  259.         if (data == null) {  
  260.             return 0;  
  261.         }  
  262.   
  263.         // count characters that's not whitespace  
  264.         int newSize = 0;  
  265.         int len = data.length;  
  266.         for (int i = 0; i < len; i++) {  
  267.             if (!isWhiteSpace(data[i])) {  
  268.                 data[newSize++] = data[i];  
  269.             }  
  270.         }  
  271.         return newSize;  
  272.     }  
  273. }  

最后是一个MainTest:

  1. package com.ihep;  
  2.   
  3. public class MainTest {  
  4.   
  5.     public static void main(String[] args) throws Exception {  
  6.         String filepath="G:/tmp/";  
  7.   
  8.         //RSAEncrypt.genKeyPair(filepath);  
  9.           
  10.           
  11.         System.out.println("--------------公钥加密私钥解密过程-------------------");  
  12.         String plainText="ihep_公钥加密私钥解密";  
  13.         //公钥加密过程  
  14.         byte[] cipherData=RSAEncrypt.encrypt(RSAEncrypt.loadPublicKeyByStr(RSAEncrypt.loadPublicKeyByFile(filepath)),plainText.getBytes());  
  15.         String cipher=Base64.encode(cipherData);  
  16.         //私钥解密过程  
  17.         byte[] res=RSAEncrypt.decrypt(RSAEncrypt.loadPrivateKeyByStr(RSAEncrypt.loadPrivateKeyByFile(filepath)), Base64.decode(cipher));  
  18.         String restr=new String(res);  
  19.         System.out.println("原文:"+plainText);  
  20.         System.out.println("加密:"+cipher);  
  21.         System.out.println("解密:"+restr);  
  22.         System.out.println();  
  23.           
  24.         System.out.println("--------------私钥加密公钥解密过程-------------------");  
  25.         plainText="ihep_私钥加密公钥解密";  
  26.         //私钥加密过程  
  27.         cipherData=RSAEncrypt.encrypt(RSAEncrypt.loadPrivateKeyByStr(RSAEncrypt.loadPrivateKeyByFile(filepath)),plainText.getBytes());  
  28.         cipher=Base64.encode(cipherData);  
  29.         //公钥解密过程  
  30.         res=RSAEncrypt.decrypt(RSAEncrypt.loadPublicKeyByStr(RSAEncrypt.loadPublicKeyByFile(filepath)), Base64.decode(cipher));  
  31.         restr=new String(res);  
  32.         System.out.println("原文:"+plainText);  
  33.         System.out.println("加密:"+cipher);  
  34.         System.out.println("解密:"+restr);  
  35.         System.out.println();  
  36.           
  37.         System.out.println("---------------私钥签名过程------------------");  
  38.         String content="ihep_这是用于签名的原始数据";  
  39.         String signstr=RSASignature.sign(content,RSAEncrypt.loadPrivateKeyByFile(filepath));  
  40.         System.out.println("签名原串:"+content);  
  41.         System.out.println("签名串:"+signstr);  
  42.         System.out.println();  
  43.           
  44.         System.out.println("---------------公钥校验签名------------------");  
  45.         System.out.println("签名原串:"+content);  
  46.         System.out.println("签名串:"+signstr);  
  47.           
  48.         System.out.println("验签结果:"+RSASignature.doCheck(content, signstr, RSAEncrypt.loadPublicKeyByFile(filepath)));  
  49.         System.out.println();  
  50.           
  51.     }  
  52. }  

看看运行截图:



转载请注明:http://blog.csdn.net/wangqiuyun/article/details/42143957



总结:

不要去硬记。
你只要想:既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密;同理,既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。

posted @ 2018-03-14 16:13  星朝  阅读(798)  评论(0编辑  收藏  举报