RSA加密工具包

主要参考: http://www.blogjava.net/icewee/archive/2012/05/19/378570.html

http://snowolf.iteye.com/

基于以上代码汇总而成:

实现效果

1生成公钥私钥. 保存在内存/文件中.

2从文件或者内存中读取公钥私钥.加密.

3加密后传输过程中,使用hex加密.

-------------------------------------------------------------------------------------

Coder 基础加密组件

  1 package com.test;
  2 
  3 import java.security.MessageDigest;
  4 
  5 import javax.crypto.KeyGenerator;
  6 import javax.crypto.Mac;
  7 import javax.crypto.SecretKey;
  8 import javax.crypto.spec.SecretKeySpec;
  9 
 10 import sun.misc.BASE64Decoder;
 11 import sun.misc.BASE64Encoder;
 12 
 13 /**
 14  * 基础加密组件
 15  * @author 梁栋
 16  * @version 1.0
 17  * @since 1.0
 18  */
 19 public abstract class Coder {
 20     public static final String KEY_SHA = "SHA";
 21     public static final String KEY_MD5 = "MD5";
 22 
 23     /**
 24      * MAC算法可选以下多种算法
 25      * 
 26      * <pre>
 27      * HmacMD5 
 28      * HmacSHA1 
 29      * HmacSHA256 
 30      * HmacSHA384 
 31      * HmacSHA512
 32      * </pre>
 33      */
 34     public static final String KEY_MAC = "HmacMD5";
 35 
 36     /**
 37      * BASE64解密
 38      * 
 39      * @param key
 40      * @return
 41      * @throws Exception
 42      */
 43     public static byte[] decryptBASE64(String key) throws Exception {
 44         return (new BASE64Decoder()).decodeBuffer(key);
 45     }
 46 
 47     /**
 48      * BASE64加密
 49      * 
 50      * @param key
 51      * @return
 52      * @throws Exception
 53      */
 54     public static String encryptBASE64(byte[] key) throws Exception {
 55         return (new BASE64Encoder()).encodeBuffer(key);
 56     }
 57 
 58     /**
 59      * MD5加密
 60      * 
 61      * @param data
 62      * @return
 63      * @throws Exception
 64      */
 65     public static byte[] encryptMD5(byte[] data) throws Exception {
 66 
 67         MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
 68         md5.update(data);
 69 
 70         return md5.digest();
 71 
 72     }
 73 
 74     /**
 75      * SHA加密
 76      * 
 77      * @param data
 78      * @return
 79      * @throws Exception
 80      */
 81     public static byte[] encryptSHA(byte[] data) throws Exception {
 82 
 83         MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
 84         sha.update(data);
 85 
 86         return sha.digest();
 87 
 88     }
 89 
 90     /**
 91      * 初始化HMAC密钥
 92      * 
 93      * @return
 94      * @throws Exception
 95      */
 96     public static String initMacKey() throws Exception {
 97         KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);
 98 
 99         SecretKey secretKey = keyGenerator.generateKey();
100         return encryptBASE64(secretKey.getEncoded());
101     }
102 
103     /**
104      * HMAC加密
105      * 
106      * @param data
107      * @param key
108      * @return
109      * @throws Exception
110      */
111     public static byte[] encryptHMAC(byte[] data, String key) throws Exception {
112 
113         SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);
114         Mac mac = Mac.getInstance(secretKey.getAlgorithm());
115         mac.init(secretKey);
116 
117         return mac.doFinal(data);
118 
119     }
120 }

RSACoder RSA加密组件

  1 package com.test;
  2 
  3 import java.security.Key;
  4 import java.security.KeyFactory;
  5 import java.security.KeyPair;
  6 import java.security.KeyPairGenerator;
  7 import java.security.PrivateKey;
  8 import java.security.PublicKey;
  9 import java.security.Signature;
 10 import java.security.interfaces.RSAPrivateKey;
 11 import java.security.interfaces.RSAPublicKey;
 12 import java.security.spec.PKCS8EncodedKeySpec;
 13 import java.security.spec.X509EncodedKeySpec;
 14 
 15 import java.util.HashMap;
 16 import java.util.Map;
 17 
 18 import javax.crypto.Cipher;
 19 
 20 /**
 21  * RSA安全编码组件
 22  * 
 23  * @author 梁栋
 24  * @version 1.0
 25  * @since 1.0
 26  */
 27 public abstract class RSACoder extends Coder {
 28     public static final String KEY_ALGORITHM = "RSA";
 29     public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
 30 
 31     private static final String PUBLIC_KEY = "RSAPublicKey";
 32     private static final String PRIVATE_KEY = "RSAPrivateKey";
 33 
 34     /**
 35      * 用私钥对信息生成数字签名
 36      * 
 37      * @param data
 38      *            加密数据
 39      * @param privateKey
 40      *            私钥
 41      * 
 42      * @return
 43      * @throws Exception
 44      */
 45     public static String sign(byte[] data, String privateKey) throws Exception {
 46         // 解密由base64编码的私钥
 47         byte[] keyBytes = decryptBASE64(privateKey);
 48 
 49         // 构造PKCS8EncodedKeySpec对象
 50         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
 51 
 52         // KEY_ALGORITHM 指定的加密算法
 53         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
 54 
 55         // 取私钥匙对象
 56         PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
 57 
 58         // 用私钥对信息生成数字签名
 59         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
 60         signature.initSign(priKey);
 61         signature.update(data);
 62 
 63         return encryptBASE64(signature.sign());
 64     }
 65 
 66     /**
 67      * 校验数字签名
 68      * 
 69      * @param data
 70      *            加密数据
 71      * @param publicKey
 72      *            公钥
 73      * @param sign
 74      *            数字签名
 75      * 
 76      * @return 校验成功返回true 失败返回false
 77      * @throws Exception
 78      * 
 79      */
 80     public static boolean verify(byte[] data, String publicKey, String sign)
 81             throws Exception {
 82 
 83         // 解密由base64编码的公钥
 84         byte[] keyBytes = decryptBASE64(publicKey);
 85 
 86         // 构造X509EncodedKeySpec对象
 87         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
 88 
 89         // KEY_ALGORITHM 指定的加密算法
 90         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
 91 
 92         // 取公钥匙对象
 93         PublicKey pubKey = keyFactory.generatePublic(keySpec);
 94 
 95         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
 96         signature.initVerify(pubKey);
 97         signature.update(data);
 98 
 99         // 验证签名是否正常
100         return signature.verify(decryptBASE64(sign));
101     }
102 
103     /**
104      * 解密<br>
105      * 用私钥解密
106      * 
107      * @param data
108      * @param key
109      * @return
110      * @throws Exception
111      */
112     public static byte[] decryptByPrivateKey(byte[] data, String key)
113             throws Exception {
114         // 对密钥解密
115         byte[] keyBytes = decryptBASE64(key);
116 
117         // 取得私钥
118         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
119         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
120         Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
121 
122         // 对数据解密
123         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
124         cipher.init(Cipher.DECRYPT_MODE, privateKey);
125 
126         return cipher.doFinal(data);
127     }
128 
129     /**
130      * 解密<br>
131      * 用公钥解密
132      * 
133      * @param data
134      * @param key
135      * @return
136      * @throws Exception
137      */
138     public static byte[] decryptByPublicKey(byte[] data, String key)
139             throws Exception {
140         // 对密钥解密
141         byte[] keyBytes = decryptBASE64(key);
142 
143         // 取得公钥
144         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
145         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
146         Key publicKey = keyFactory.generatePublic(x509KeySpec);
147 
148         // 对数据解密
149         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
150         cipher.init(Cipher.DECRYPT_MODE, publicKey);
151 
152         return cipher.doFinal(data);
153     }
154 
155     /**
156      * 加密<br>
157      * 用公钥加密
158      * 
159      * @param data
160      * @param key
161      * @return
162      * @throws Exception
163      */
164     public static byte[] encryptByPublicKey(byte[] data, String key)
165             throws Exception {
166         // 对公钥解密
167         byte[] keyBytes = decryptBASE64(key);
168 
169         // 取得公钥
170         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
171         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
172         Key publicKey = keyFactory.generatePublic(x509KeySpec);
173 
174         // 对数据加密
175         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
176         cipher.init(Cipher.ENCRYPT_MODE, publicKey);
177 
178         return cipher.doFinal(data);
179     }
180 
181     /**
182      * 加密<br>
183      * 用私钥加密
184      * 
185      * @param data
186      * @param key
187      * @return
188      * @throws Exception
189      */
190     public static byte[] encryptByPrivateKey(byte[] data, String key)
191             throws Exception {
192         // 对密钥解密
193         byte[] keyBytes = decryptBASE64(key);
194 
195         // 取得私钥
196         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
197         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
198         Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
199 
200         // 对数据加密
201         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
202         cipher.init(Cipher.ENCRYPT_MODE, privateKey);
203 
204         return cipher.doFinal(data);
205     }
206 
207     /**
208      * 取得私钥
209      * 
210      * @param keyMap
211      * @return
212      * @throws Exception
213      */
214     public static String getPrivateKey(Map<String, Object> keyMap)
215             throws Exception {
216         Key key = (Key) keyMap.get(PRIVATE_KEY);
217 
218         return encryptBASE64(key.getEncoded());
219     }
220 
221     /**
222      * 取得公钥
223      * 
224      * @param keyMap
225      * @return
226      * @throws Exception
227      */
228     public static String getPublicKey(Map<String, Object> keyMap)
229             throws Exception {
230         Key key = (Key) keyMap.get(PUBLIC_KEY);
231         return encryptBASE64(key.getEncoded());
232     }
233 
234     /**
235      * 初始化密钥
236      * 
237      * @return
238      * @throws Exception
239      */
240     public static Map<String, Object> initKey() throws Exception {
241         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
242         keyPairGen.initialize(1024);
243 
244         KeyPair keyPair = keyPairGen.generateKeyPair();
245 
246         // 公钥
247         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
248 
249         // 私钥
250         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
251 
252         Map<String, Object> keyMap = new HashMap<String, Object>(2);
253 
254         keyMap.put(PUBLIC_KEY, publicKey);
255         keyMap.put(PRIVATE_KEY, privateKey);
256         return keyMap;
257     }
258 }

base64Util base加密解密工具类

 1 package com.test;
 2 
 3 import sun.misc.BASE64Decoder;
 4 import sun.misc.BASE64Encoder;
 5 
 6 /**
 7  * BASE64 严格地说,属于编码格式,而非加密算法
 8  * Base64被定义为:Base64内容传送编码被设计用来
 9  *     把任意序列的8位字节描述为一种不易被人直接识别的形式。
10  *  常见于邮件、http加密,截取http信息,你就会发现登录操
11  *  作的用户名、密码字段通过BASE64加密的。 
12  * @author Z10
13  * @time 2014-7-4 上午10:41:11
14  */
15 public class base64Util {
16 
17     public static void main(String[] args) {
18         String str ="我是James. 今年1岁。";
19 //        String str ="Ilovepolly";
20         System.out.println("加密前"+str);
21         String enStr = null;
22         String deStr = null;
23         String deStr2 = null;
24         try {
25             enStr = base64Util.encryptBASE64(str.getBytes());
26             deStr = (base64Util.decryptBASE64(enStr)).toString();    //错误用法无法将byte转为string
27             deStr2 = new String(base64Util.decryptBASE64(enStr));
28         } catch (Exception e) {
29             e.printStackTrace();
30         }
31         System.out.println("加密后"+enStr);
32         System.out.println("解密后"+deStr);
33         System.out.println("解密后"+deStr2);
34 
35     }
36     
37     /**
38      * BASE64解密
39      * 
40      * @param key
41      * @return
42      * @throws Exception
43      */
44     public static byte[] decryptBASE64(String key) throws Exception {
45         return (new BASE64Decoder()).decodeBuffer(key);
46     }
47 
48     /**
49      * BASE64加密
50      * 
51      * @param key
52      * @return
53      * @throws Exception
54      */
55     public static String encryptBASE64(byte[] key) throws Exception {
56         return (new BASE64Encoder()).encodeBuffer(key);
57     }
58 }

十六进制/2进制转换工具类 hex-byte

MyUtils

 1 package com.test.util;
 2 
 3 import java.io.UnsupportedEncodingException;
 4 
 5 public abstract class MyUtils {
 6     
 7     public static char[] hex={'0','1','2','3',
 8                               '4','5','6','7',
 9                               '8','9','a','b',
10                               'c','d','e','f',};
11     
12     public static String byteToHex(byte[] encode){
13         
14         StringBuffer sb = new StringBuffer();
15         
16         for(int i=0;i<encode.length;i++){
17             sb.append(hex[(encode[i]>>>4) & 0xF]);//按照字节序列,从高位到低位进行解析
18             sb.append(hex[encode[i] & 0xF]);
19         }
20         
21         return sb.toString();
22     }
23     
24     public static byte[] hexToByte(String strIn) throws Exception{
25         
26             byte[] buf=new byte[strIn.length()/2];
27             
28             for(int i=0;i<strIn.length();i=i+2){
29                 String s = strIn.substring(i, i+2);
30                 buf[i/2]= (byte) Integer.parseInt(s,16);
31             }
32         
33             return buf;
34 //            System.out.println(strIn.length());
35 //            byte[] arrB = strIn.getBytes("UTF-8");
36 //            int iLen = arrB.length;
37 //
38 //            // 两个字符表示一个字节,所以字节数组长度是字符串长度除以2
39 //            byte[] arrOut = new byte[iLen / 2];
40 //            System.out.println(arrOut.length);
41 //            for (int i = 0; i < iLen; i = i + 2) {
42 //                String strTmp = new String(arrB, i, 2, "UTF-8");
43 //                arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
44 //            }
45 //            return arrOut;
46     }
47 
48 }

实际RSA加密解密工具类RSAUtils_V2

  1 package com.test.Rsa;
  2 import java.io.ByteArrayOutputStream;
  3 import java.io.File;
  4 import java.io.FileInputStream;
  5 import java.io.IOException;
  6 import java.security.InvalidKeyException;
  7 import java.security.Key;
  8 import java.security.KeyFactory;
  9 import java.security.KeyPair;
 10 import java.security.KeyPairGenerator;
 11 import java.security.NoSuchAlgorithmException;
 12 import java.security.PrivateKey;
 13 import java.security.PublicKey;
 14 import java.security.Signature;
 15 import java.security.interfaces.RSAPrivateKey;
 16 import java.security.interfaces.RSAPublicKey;
 17 import java.security.spec.EncodedKeySpec;
 18 import java.security.spec.InvalidKeySpecException;
 19 import java.security.spec.PKCS8EncodedKeySpec;
 20 import java.security.spec.X509EncodedKeySpec;
 21 import java.util.HashMap;
 22 import java.util.Map;
 23 
 24 import javax.crypto.BadPaddingException;
 25 import javax.crypto.Cipher;
 26 import javax.crypto.IllegalBlockSizeException;
 27 import javax.crypto.NoSuchPaddingException;
 28 
 29 import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
 30 import com.test.util.RSACoder;
 31 
 32 /** *//**
 33  * <p>
 34  * RSA公钥/私钥/签名工具包 v2 UPDATE BY ZYL
 35  * </p>
 36  * <p>
 37  * 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman)
 38  * </p>
 39  * <p>
 40  * 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/>
 41  * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
 42  * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
 43  * </p>
 44  * <P>
 45  * 版本2更新变化:
 46  * 1原版本密钥创建后保存在内存map中,新版本密钥创建后保存为public.key,private.key的功能(base64解码后保存).
 47  * 2为保证生成文件的密钥内容可以显示并缩短加密后的长度,对需加密内容进行hex(16进制转换)处理后再加密.
 48  *  即
 49  * </P>
 50  * 
 51  * @author IceWee
 52  * @date 2012-4-26
 53  * @version 1.0
 54  */
 55 public class RSAUtils_V2 {
 56 
 57     /** *//**
 58      * 加密算法RSA
 59      */
 60     public static final String KEY_ALGORITHM = "RSA";
 61     
 62     /** *//**
 63      * 签名算法
 64      */
 65     public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
 66 
 67     /** *//**
 68      * 获取公钥的key
 69      */
 70     private static final String PUBLIC_KEY = "RSAPublicKey";
 71     
 72     /** *//**
 73      * 获取私钥的key
 74      */
 75     private static final String PRIVATE_KEY = "RSAPrivateKey";
 76     
 77     /** *//**
 78      * RSA最大加密明文大小
 79      */
 80     private static final int MAX_ENCRYPT_BLOCK = 117;
 81     
 82     /** *//**
 83      * RSA最大解密密文大小
 84      */
 85     private static final int MAX_DECRYPT_BLOCK = 128;
 86 
 87     /** *//**
 88      * <p>
 89      * 生成密钥对(公钥和私钥)
 90      * </p>
 91      * @return
 92      * @throws Exception
 93      */
 94     public static Map<String, Object> genKeyPair() throws Exception {
 95         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);//"RSA"
 96         keyPairGen.initialize(1024);
 97         KeyPair keyPair = keyPairGen.generateKeyPair();//Generates a key pair 生成公钥私钥.
 98         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//取得公钥
 99         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();//取得私钥
100         Map<String, Object> keyMap = new HashMap<String, Object>(2);
101         keyMap.put(PUBLIC_KEY, publicKey);
102         keyMap.put(PRIVATE_KEY, privateKey);
103         return keyMap;
104     }
105     
106     /**
107      * 将公钥私钥(默认base64加密)并转为公钥/私钥字符串还原为对应公钥/私钥  
108      * by    Z10
109      * @param keyType (publicKey / privateKey)
110      * @param keystr
111      * @return
112      * @throws Exception 
113      */
114      public Key getKeybyKeyStr(String keyType,String keystr) throws Exception{
115          if(keyType==null||!keyType.equals("")){
116              throw new Exception("keyType can not be null");
117          }
118          //需要返回公钥
119          if(keyType.equals(keyType)){
120              byte[] keyBytes = Base64Utils.decode(keystr);
121              X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
122              KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
123              Key publicK = keyFactory.generatePublic(x509KeySpec);
124              return publicK;
125          }
126          //需要返回私钥
127          else if(keyType.equals("privateKey")){
128              byte[] keyBytes = Base64Utils.decode(keystr);
129              PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
130              KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
131              Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
132              return privateK;
133          }else{
134              throw new Exception("keyType'value is incorrect");
135          }
136      }
137      
138      /**
139      * 根据传入的key文件名生成对应key文件. by zyl
140      * @throws IOException 
141      * @throws NoSuchAlgorithmException 
142      * @throws InvalidKeySpecException 
143       */
144      public static Map<String, Object> getKeyByFile() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException{
145         Map<String, Object> keyMap = new HashMap<String, Object>(2);
146         FileInputStream fin = new FileInputStream(new File("public.key"));
147             byte[] buf = new byte[fin.available()];
148             fin.read(buf);
149             X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Base64.decode(new String(buf)));
150             // 构建key工厂
151             KeyFactory keyFactory = KeyFactory.getInstance("RSA");
152             // 获取到完整的publickey对象
153             PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
154         FileInputStream fin2 = new FileInputStream(new File("private.key"));
155             byte[] buf2=new byte[fin2.available()];
156             fin2.read(buf2);
157             KeyFactory keyFactory2 = KeyFactory.getInstance("RSA");
158             @SuppressWarnings("static-access")
159             EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(new Base64().decode(new String(buf2)));
160             // 获取到完整的privatekey对象
161             PrivateKey privateKey = keyFactory2.generatePrivate(privateKeySpec);
162         keyMap.put(PUBLIC_KEY, publicKey);
163         keyMap.put(PRIVATE_KEY, privateKey);
164         return keyMap;
165      }
166      
167      /**
168       * 生成密钥文本文件
169      * @throws Exception 
170       */
171      public static void createKeyFile(Map<String, Object> keyMap) throws Exception{
172          //生成公钥
173          String publicKey_Str=RSACoder.getPublicKey(keyMap);
174          byte[] bytes1=publicKey_Str.getBytes("UTF-8");
175          Base64Utils.byteArrayToFile(bytes1, "public.key");
176          
177          //生成私钥
178          String privateKey_Str=RSACoder.getPrivateKey(keyMap);
179          byte[] bytes2=privateKey_Str.getBytes("UTF-8");
180          Base64Utils.byteArrayToFile(bytes2, "private.key");
181          
182      }
183     
184     /** *//**
185      * <p>
186      * 用私钥对信息生成数字签名
187      * </p>
188      * 
189      * @param data 已加密数据
190      * @param privateKey 私钥(BASE64编码)
191      * 
192      * @return
193      * @throws Exception
194      */
195     public static String sign(byte[] data, String privateKey) throws Exception {
196         byte[] keyBytes = Base64Utils.decode(privateKey);
197         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
198         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
199         PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
200         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
201         signature.initSign(privateK);
202         signature.update(data);
203         return Base64Utils.encode(signature.sign());
204     }
205 
206     /** *//**
207      * 校验数字签名
208      * </p>
209      * @param data 已加密数据
210      * @param publicKey 公钥(BASE64编码)
211      * @param sign 数字签名
212      * @return
213      * @throws Exception
214      */
215     public static boolean verify(byte[] data, String publicKey, String sign)
216             throws Exception {
217         byte[] keyBytes = Base64Utils.decode(publicKey);
218         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
219         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
220         PublicKey publicK = keyFactory.generatePublic(keySpec);
221         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
222         signature.initVerify(publicK);
223         signature.update(data);
224         return signature.verify(Base64Utils.decode(sign));
225     }
226 
227     
228     /**
229      *私钥解密 by zyl 
230      */
231     public static byte[] decryptByPrivateKey(byte[] encryptedData, Key privateKey)throws Exception {
232         Cipher cipher = Cipher.getInstance("RSA");
233         cipher.init(Cipher.DECRYPT_MODE, privateKey);
234         int inputLen = encryptedData.length;
235         ByteArrayOutputStream out = new ByteArrayOutputStream();
236         int offSet = 0;
237         byte[] cache;
238         int i = 0;
239         // 对数据分段解密
240         while (inputLen - offSet > 0) {
241             if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
242                 cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
243             } else {
244                 cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
245             }
246             out.write(cache, 0, cache.length);
247             i++;
248             offSet = i * MAX_DECRYPT_BLOCK;
249         }
250         byte[] decryptedData = out.toByteArray();
251         out.close();
252         return decryptedData;
253     }
254     
255     /** *//**
256      * 私钥解密
257      * </p>
258      * @param encryptedData 已加密数据
259      * @param privateKey 私钥(BASE64编码)
260      * @return
261      * @throws Exception
262      */
263     public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
264             throws Exception {
265         byte[] keyBytes = Base64Utils.decode(privateKey);
266         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
267         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
268         Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
269         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
270         cipher.init(Cipher.DECRYPT_MODE, privateK);
271         int inputLen = encryptedData.length;
272         ByteArrayOutputStream out = new ByteArrayOutputStream();
273         int offSet = 0;
274         byte[] cache;
275         int i = 0;
276         // 对数据分段解密
277         while (inputLen - offSet > 0) {
278             if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
279                 cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
280             } else {
281                 cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
282             }
283             out.write(cache, 0, cache.length);
284             i++;
285             offSet = i * MAX_DECRYPT_BLOCK;
286         }
287         byte[] decryptedData = out.toByteArray();
288         out.close();
289         return decryptedData;
290     }
291     
292     
293     /** *//**
294      * 公钥解密
295      * </p>
296      * @param encryptedData 已加密数据
297      * @param publicKey 公钥(BASE64编码)
298      * @return
299      * @throws Exception
300      */
301     public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)
302             throws Exception {
303         
304         byte[] keyBytes = Base64Utils.decode(publicKey);
305         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
306         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
307         Key publicK = keyFactory.generatePublic(x509KeySpec);
308         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
309         cipher.init(Cipher.DECRYPT_MODE, publicK);
310         int inputLen = encryptedData.length;
311         ByteArrayOutputStream out = new ByteArrayOutputStream();
312         int offSet = 0;
313         byte[] cache;
314         int i = 0;
315         // 对数据分段解密
316         while (inputLen - offSet > 0) {
317             if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
318                 cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
319             } else {
320                 cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
321             }
322             out.write(cache, 0, cache.length);
323             i++;
324             offSet = i * MAX_DECRYPT_BLOCK;
325         }
326         byte[] decryptedData = out.toByteArray();
327         out.close();
328         return decryptedData;
329     }
330 
331     /**
332      * 公钥加密 by zyl
333      * @param data
334      * @param publicKey
335      * @return
336      */
337     public static byte[] encryptByPublicKey(byte[] data, Key publicKey) throws Exception{
338         // 对数据加密
339         /*根据公钥加密*/
340         Cipher cipher = Cipher.getInstance("RSA");
341         cipher.init(Cipher.ENCRYPT_MODE,publicKey);
342         int inputLen = data.length;
343         ByteArrayOutputStream out = new ByteArrayOutputStream();
344         int offSet = 0;
345         byte[] cache;
346         int i = 0;
347         // 对数据分段加密
348         while (inputLen - offSet > 0) {
349             if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
350                 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
351             } else {
352                 cache = cipher.doFinal(data, offSet, inputLen - offSet);
353             }
354             out.write(cache, 0, cache.length);
355             i++;
356             offSet = i * MAX_ENCRYPT_BLOCK;
357         }
358         byte[] encryptedData = out.toByteArray();
359         out.close();
360         return encryptedData;
361     }
362     
363     /**<p>
364      * 公钥加密
365      * </p>
366      * @param data 源数据
367      * @param publicKey 公钥(BASE64编码)
368      * @return
369      * @throws Exception
370      */
371     public static byte[] encryptByPublicKey(byte[] data, String publicKey)
372             throws Exception {
373         byte[] keyBytes = Base64Utils.decode(publicKey);
374         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
375         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
376         Key publicK = keyFactory.generatePublic(x509KeySpec);
377         // 对数据加密
378         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
379         cipher.init(Cipher.ENCRYPT_MODE, publicK);
380         int inputLen = data.length;
381         ByteArrayOutputStream out = new ByteArrayOutputStream();
382         int offSet = 0;
383         byte[] cache;
384         int i = 0;
385         // 对数据分段加密
386         while (inputLen - offSet > 0) {
387             if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
388                 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
389             } else {
390                 cache = cipher.doFinal(data, offSet, inputLen - offSet);
391             }
392             out.write(cache, 0, cache.length);
393             i++;
394             offSet = i * MAX_ENCRYPT_BLOCK;
395         }
396         byte[] encryptedData = out.toByteArray();
397         out.close();
398         return encryptedData;
399     }
400 
401     /**
402      * 私钥加密by zyl
403      */
404     public static byte[] encryptByPrivateKey(byte[] data, Key privateKey)throws Exception {
405         Cipher cipher = Cipher.getInstance("RSA");
406         cipher.init(Cipher.ENCRYPT_MODE, privateKey);
407         int inputLen = data.length;
408         ByteArrayOutputStream out = new ByteArrayOutputStream();
409         int offSet = 0;
410         byte[] cache;
411         int i = 0;
412         // 对数据分段加密
413         while (inputLen - offSet > 0) {
414             if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
415                 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
416             } else {
417                 cache = cipher.doFinal(data, offSet, inputLen - offSet);
418             }
419             out.write(cache, 0, cache.length);
420             i++;
421             offSet = i * MAX_ENCRYPT_BLOCK;
422         }
423         byte[] encryptedData = out.toByteArray();
424         out.close();
425         return encryptedData;
426     }
427     
428     
429     /** *//**
430      * <p>
431      * 私钥加密
432      * </p>
433      * @param data 源数据
434      * @param privateKey 私钥(BASE64编码)
435      * @return
436      * @throws Exception
437      */
438     public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
439             throws Exception {
440         byte[] keyBytes = Base64Utils.decode(privateKey);
441         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
442         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
443         Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
444         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
445         cipher.init(Cipher.ENCRYPT_MODE, privateK);
446         int inputLen = data.length;
447         ByteArrayOutputStream out = new ByteArrayOutputStream();
448         int offSet = 0;
449         byte[] cache;
450         int i = 0;
451         // 对数据分段加密
452         while (inputLen - offSet > 0) {
453             if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
454                 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
455             } else {
456                 cache = cipher.doFinal(data, offSet, inputLen - offSet);
457             }
458             out.write(cache, 0, cache.length);
459             i++;
460             offSet = i * MAX_ENCRYPT_BLOCK;
461         }
462         byte[] encryptedData = out.toByteArray();
463         out.close();
464         return encryptedData;
465     }
466 
467     /** *//**
468      * <p>
469      * 获取私钥
470      * </p>
471      * @param keyMap 密钥对
472      * @return
473      * @throws Exception
474      */
475     public static String getPrivateKey(Map<String, Object> keyMap)
476             throws Exception {
477         Key key = (Key) keyMap.get(PRIVATE_KEY);
478         return Base64Utils.encode(key.getEncoded());
479     }
480 
481     /** *//**
482      * <p>
483      * 获取公钥
484      * </p>
485      * @param keyMap 密钥对
486      * @return
487      * @throws Exception
488      */
489     public static String getPublicKey(Map<String, Object> keyMap)
490             throws Exception {
491         Key key = (Key) keyMap.get(PUBLIC_KEY);
492         return Base64Utils.encode(key.getEncoded());
493     }
494 }

测试类:

testRSAUnitsV2

  1 package com.rsa.test;
  2 
  3 import java.security.Key;
  4 import java.util.Map;
  5 
  6 import org.junit.Test;
  7 
  8 import com.test.Rsa.RSAUtils_V2;
  9 import com.test.util.MyUtils;
 10 
 11 public class testRSAUnitsV2 {
 12 
 13     static String publicKey2;
 14     static String privateKey2;
 15     
 16      public static void main(String args[]){
 17          try {
 18             test3();
 19         } catch (Exception e) {
 20             e.printStackTrace();
 21         }
 22          
 23      }
 24     
 25     /**
 26      * 加密解密
 27      * @throws Exception 
 28      */
 29     /**
 30      * 生成密钥对,并保存为对应文本文件.
 31      */
 32     public void test1() {
 33         RSAUtils_V2 r2=new RSAUtils_V2();
 34         try {
 35             Map<String, Object> keyMap=RSAUtils_V2.genKeyPair();
 36             RSAUtils_V2.createKeyFile(keyMap);
 37         } catch (Exception e) {
 38             e.printStackTrace();
 39         }
 40     }
 41     
 42     /**
 43      * 1读取test()方法中生成的密钥文件, 并在内存中生成密钥
 44      * 2使用密钥加密解密文本.
 45      */
 46     public static void test2() {
 47         try {
 48             Map<String, Object> keyMap2=RSAUtils_V2.getKeyByFile();
 49             publicKey2 = RSAUtils_V2.getPublicKey(keyMap2);//获取公钥
 50             privateKey2 = RSAUtils_V2.getPrivateKey(keyMap2);//获取私钥
 51             System.err.println("公钥: 

" + publicKey2);
 52             System.err.println("私钥: 

" + privateKey2);
 53             
 54             String str="这是一行没有任何意义的文字,你看完了等于没看,不是吗?";//.来加密我吧.I M KEY!
 55             System.out.println(" 加密前="+str);
 56             byte[] jiami=RSAUtils_V2.encryptByPublicKey(str.getBytes(), (Key)keyMap2.get("RSAPublicKey"));
 57             System.out.println(" 加密后="+new String(jiami));
 58             
 59             byte[] jiami2=RSAUtils_V2.decryptByPrivateKey(jiami, (Key)keyMap2.get("RSAPrivateKey"));
 60             System.out.println(" 解密后="+new String(jiami2));
 61         }catch (Exception e) {
 62             e.printStackTrace();
 63         }
 64     }
 65     /**
 66      * test2基础上:
 67      * 加密后可以对byte进行hex.这样内容就不是乱码,大小更小,也便于进行传播.
 68      * 解密前对hex进行转换hex2byte即可,然后解密即可
 69      */
 70     public static void test3(){
 71         try {
 72             Map<String, Object> keyMap2 = RSAUtils_V2.getKeyByFile();
 73             publicKey2 = RSAUtils_V2.getPublicKey(keyMap2);//获取公钥
 74             privateKey2 = RSAUtils_V2.getPrivateKey(keyMap2);//获取私钥
 75             System.err.println("公钥: 

" + publicKey2);
 76             System.err.println("私钥: 

" + privateKey2);
 77             String str = "这是一行没有任何意义的文字,你看完了等于没看,不是吗?据说长度太长会有问题.于是:" +
 78                     "日前拜仁董事会主席鲁梅尼格表示,鉴于目前球员们的比赛压力太大,国家队比赛场次应当减少。" +
 79                     "鲁梅尼格表示:“球员们的压力早已经超过了健康的范围之内,已经达到了身体所允许的上限。国家队" +
 80                     "比赛的增长是有责任的。”鲁梅尼格呼吁国际足联以及欧足联减少国家队比赛次数。“比赛应当以质量而不" +
 81                     "是数量为目标。”另外鲁梅尼格举出具体的数字表示,在过去的几十年里,球员们国家队的比赛数量增长了30%," +
 82                     "“贝肯鲍尔时代的球员们每年只需要参加8.5场国家队比赛,而穆勒们则需要参加大概13场。”而俱乐部则必须承担国" +
 83                     "家队比赛增多的风险。在周末的德甲联赛中拜仁客场0-0与汉堡互交白卷,赛前球队中场罗本已经进入首发阵容,但不慎" +
 84                     "在热身时受伤。据报道,罗本或将继续无缘拜仁下场对阵帕德博恩的比赛。在对阵汉堡的比赛前罗本已经被列入球队首发,但在热身时罗本再度受伤。“肌肉感觉有些紧。”随后原本计划被轮换的穆勒临时出场替代罗本。另外罗本表示这只是预防措施。但球队下一场对阵帕德博恩能够出场,罗本表示:“我也不能确定。”";//.来加密我吧.I M KEY!
 85             System.out.println(" 加密前=" + str);
 86             byte[] jiami = RSAUtils_V2.encryptByPublicKey(str.getBytes(),
 87                     (Key) keyMap2.get("RSAPublicKey"));
 88             System.out.println(" 加密后=" + new String(jiami));
 89             System.out.println(" 加密后长度=" + jiami.length);
 90             //加密后hex
 91             String afterhex=MyUtils.byteToHex(jiami);
 92             System.out.println(" 加密并hex后=" + new String(afterhex));
 93             System.out.println(" 加密并hex后长度=" + afterhex.length());
 94             //反hex
 95             byte[] afterReHEX=MyUtils.hexToByte(afterhex);
 96             byte[] jiami2 = RSAUtils_V2.decryptByPrivateKey(afterReHEX,
 97                     (Key) keyMap2.get("RSAPrivateKey"));
 98             System.out.println(" 解密后=" + new String(jiami2));
 99             System.out.println(" 解密后长度=" + jiami2.length);
100         } catch (Exception e) {
101         }
102     }
103 }

执行test3 效果如下:

公钥: 

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCRM6FQTDPWppMTOJ3HFrpinxGUhQtQhaPXIGFBuwsqx3QsuJmVIX3DpJ0KU3cEUumDMM6qkTvFGtoIDeYQxuslUWCMFm+ma7DoDS+3RQ6nExQ5F3cTXhvXosrYYcADKP6pk8fVIiY+cq+yq/KV0OB6yOJ96N4wywhe6y3hldUXcwIDAQAB
私钥: 

MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJEzoVBMM9amkxM4nccWumKfEZSFC1CFo9cgYUG7CyrHdCy4mZUhfcOknQpTdwRS6YMwzqqRO8Ua2ggN5hDG6yVRYIwWb6ZrsOgNL7dFDqcTFDkXdxNeG9eiythhwAMo/qmTx9UiJj5yr7Kr8pXQ4HrI4n3o3jDLCF7rLeGV1RdzAgMBAAECgYBV0DmqBx8r4M5TMcatftUwq+nr6KVDNXgbD9vqyOxUoAQc2gyKgnydP5BAJgvU1luDWTkKvUKhvrjUwcIScD1PrhyecjVMqb8tvmexefd1bcPq9OZpxQjR64pwRPjC7krOENR5moiIKhngSk4Qp/dk/xX6l+h+wLlBjneQsVDxYQJBAOFDuPitRRPds+vd33lYNr2IEiJkvIErxZUXRu4Pfc/e4m03dcyhJ3eqn7KoBL4trYQsboYl3HYpDkHfHxWMCf0CQQClA2M2KdBB1F7Kb0TymM5CtvNfBsSqADspkJeCmANwCNPKW4hzq++YyfFX5cqkSuuTlS+7vjvlCgYiXDjpVuovAkEAvIjU0HUcopLk2l1Zg5L8RccT/ms3hhjfhnfz6p1WnFscQXKwijK6+KH6hSmwxocuebhCTM51ZQPZpfIbbwpE9QJAdN/LW0eOW7HhWZwpx3H3VUVjZsDSdl4niS8CQNsOREHcUA04vkTfNOaDa/Az8N2nsSYPYvhAT98jrR6IqKyIvQJAda1Kya8NLWtSbmHBldqhjSxhkEZRofzHO38Qldvfs3XU4bsPZ1YkFruf8ilVdaFSVznX88YaFK9zEBBAix/KcA==
 加密前=这是一行没有任何意义的文字,你看完了等于没看,不是吗?据说长度太长会有问题.于是:日前拜仁董事会主席鲁梅尼格表示,鉴于目前球员们的比赛压力太大,国家队比赛场次应当减少。鲁梅尼格表示:“球员们的压力早已经超过了健康的范围之内,已经达到了身体所允许的上限。国家队比赛的增长是有责任的。”鲁梅尼格呼吁国际足联以及欧足联减少国家队比赛次数。“比赛应当以质量而不是数量为目标。”另外鲁梅尼格举出具体的数字表示,在过去的几十年里,球员们国家队的比赛数量增长了30%,“贝肯鲍尔时代的球员们每年只需要参加8.5场国家队比赛,而穆勒们则需要参加大概13场。”而俱乐部则必须承担国家队比赛增多的风险。在周末的德甲联赛中拜仁客场0-0与汉堡互交白卷,赛前球队中场罗本已经进入首发阵容,但不慎在热身时受伤。据报道,罗本或将继续无缘拜仁下场对阵帕德博恩的比赛。在对阵汉堡的比赛前罗本已经被列入球队首发,但在热身时罗本再度受伤。“肌肉感觉有些紧。”随后原本计划被轮换的穆勒临时出场替代罗本。另外罗本表示这只是预防措施。但球队下一场对阵帕德博恩能够出场,罗本表示:“我也不能确定。”
 加密后=e�z]����}�t�O�`����CD��/�I�tM/��9�`�z!����W_w<��W��ޣU�|�E�)�8�z�b��.:�Ha����֏���x<�k���,���(��l�Y%�`�aM�ji?��h�����pwuy��I$
原文地址:https://www.cnblogs.com/redcoatjk/p/3985500.html