View Javadoc
1   /**
2    * Copyright By Grandsoft Company Limited.  
3    * 2014年3月18日 上午10:29:13
4    * RSA加密算法虽然不分平台,标准都是一样的,但是各个平台的实现方式都不尽相同,下面来我来说说java与.net平台之间该如何进行RSA加密验证,
5    * 即java端加密-》.net端验证和.net端加密-》java端验证。
6    * 参考资料:http://www.blogjava.net/orangehf/archive/2011/02/26/345243.html
7    */
8   package gboat2.base.bridge.util.security;
9   
10  import java.io.ByteArrayOutputStream;
11  import java.io.File;
12  import java.io.FileInputStream;
13  import java.io.FileNotFoundException;
14  import java.io.FileOutputStream;
15  import java.io.IOException;
16  import java.io.OutputStream;
17  import java.math.BigInteger;
18  import java.security.InvalidKeyException;
19  import java.security.Key;
20  import java.security.KeyFactory;
21  import java.security.KeyPair;
22  import java.security.NoSuchAlgorithmException;
23  import java.security.PrivateKey;
24  import java.security.PublicKey;
25  import java.security.interfaces.RSAPrivateCrtKey;
26  import java.security.interfaces.RSAPublicKey;
27  import java.security.spec.EncodedKeySpec;
28  import java.security.spec.KeySpec;
29  import java.security.spec.PKCS8EncodedKeySpec;
30  import java.security.spec.RSAPrivateCrtKeySpec;
31  import java.security.spec.RSAPrivateKeySpec;
32  import java.security.spec.RSAPublicKeySpec;
33  import java.security.spec.X509EncodedKeySpec;
34  import java.util.regex.Matcher;
35  import java.util.regex.Pattern;
36  
37  import javax.crypto.Cipher;
38  
39  import org.apache.commons.codec.binary.Base64;
40  import org.apache.commons.io.FileUtils;
41  import org.apache.commons.io.IOUtils;
42  import org.apache.commons.lang3.StringUtils;
43  
44  /**
45   * <p>
46   * RSA 加密、解密的工具类。如果需要与 .NET 平台进行 RSA 加密解密交互,请将加解密的 transformation 参数使用
47   * {@value #DOTNET_RSA_TRANSFORMATION}。
48   * </p>
49   * <p>
50   * 进行加解密操作时需要使用的 transformation 参数的格式为
51   * "Algorithm/Modes/Paddings",如:RSA/ECB/PKCS1Padding。RSA 加解密 Algorithm 为
52   * {@code RSA},Modes 的值只能是 {@code ECB},Paddings 的可选值有:
53   * <code>
54   * NOPADDING, PKCS1PADDING,
55   * OAEPWITHMD5ANDMGF1PADDING, OAEPWITHSHA1ANDMGF1PADDING,
56   * OAEPWITHSHA-1ANDMGF1PADDING, OAEPWITHSHA-256ANDMGF1PADDING,
57   * OAEPWITHSHA-384ANDMGF1PADDING, OAEPWITHSHA-512ANDMGF1PADDING
58   * <!-- OAEPPadding later --></code>。<br>
59   * 更多关于 transformation 参数的资料请参考
60   * <a target="_blank" href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
61   * Java Cryptography Architecture Reference Guide</a> 页面中的附录 A。
62   * 
63   * <pre>
64   * 进行加密和解密操作的示例代码:
65   *  <code>
66   * String privateKey = "MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAL6VJN4ZkfZA3aPPgKC3xaqT/yZT5FOl"
67   *         + "Q5TGg6heVqDVEHHVLH1E+HEEmWmuTv2ngz9pZbzy9KWkJpV59W1dgNHSSk575VjUAv0BhZXFSH0lng2m"
68   *         + "Z2Q5/2dVxKsASjJ2bQiEGUD8LO5KpaLlfQpo3ANovBZvUtHw5exegnyXyZbDAgMBAAECgYEAr7YEWr1K"
69   *         + "hLcDYg9jMUqd9QokOSspnTEGoPlx016/EeO/GKSJMynOwSyTYQszisvRxzoecdmyU7GHXVMnQ2Ds7Wvb"
70   *         + "cuNkIRWmxFa4nTkk2zNF6KByvvFwLiW4LQXF6B+uV7+ZNqvfhCoD/j2wki8jfWkuuAaKnTda/axHMi+z"
71   *         + "RYECQQD73iC2GjZyur4amJQPK6d+kDlJ0dYyyUvQa0vd6mfoPnQDOIqayBaueSwWIpLI/L7eUuP9CDFr"
72   *         + "yQtdBvWqD/dBAkEAwbWcrybn0eaxiPZacZLZXzXO8g12hYoXT1h0DTLvy1rnVUOspNfKZcBZMjPxT4+Q"
73   *         + "EknoTShSnSbJ5sHitfZxAwJBANMlU2z2KqEh1k77jFvvb9oVVEGDbTtkL2+JE6/1W6iB+sXcd63sgb9A"
74   *         + "i+n+j+l4oRZGjSTJ4oyGnUUemYI5IkECQQCA9JNrcv4PGYIFCOPrCfTV0m+Dan0Fp4mfE+amRsumWEz6"
75   *         + "0UOktdeS53s51aSG767czgDtJLPi1MjCaz6vHnHbAkEA4NxLLg6UCAoCpXMgqqZHWMgbMwNNFr9diCWP"
76   *         + "/tZ5OJmWYHgn7zfqMXa/RNaethjdG1biIkj5h7qm6XDBBqGuxw==";
77   * String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+lSTeGZH2QN2jz4Cgt8Wqk/8mU+RTpUOUxoOoXlag"
78   *         + "1RBx1Sx9RPhxBJlprk79p4M/aWW88vSlpCaVefVtXYDR0kpOe+VY1AL9AYWVxUh9JZ4NpmdkOf9nVcSr"
79   *         + "AEoydm0IhBlA/CzuSqWi5X0KaNwDaLwWb1LR8OXsXoJ8l8mWwwIDAQAB";
80   * 
81   * String data = "this is a test 中文";
82   * System.out.println("原文:" + data);
83   * System.out.println("--------------------------------------");
84   * 
85   * String encrypted = encryptBase64ByPrivateKey(data, privateKey);
86   * System.out.println("用私钥加密:" + encrypted);
87   * String decrypted = new String(decryptByPublicKey(encrypted, publicKey));
88   * System.out.println("用公钥解密::" + decrypted);
89   * 
90   * System.out.println("--------------------------------------");
91   * encrypted = encryptBase64ByPublicKey(data, publicKey);
92   * System.out.println("用公钥加密:" + encrypted);
93   * decrypted = new String(decryptByPrivateKey(encrypted, privateKey));
94   * System.out.println("用私钥解密::" + decrypted);
95   *  </code>
96   * </pre>
97   * @author <a href="mailto:[email protected]">何明旺</a>
98   * @since 3.0
99   * @date 2014年3月18日
100  * @see Base64Util
101  * @see CertificateUtil
102  * @see RSASignUtil
103  */
104 public class RSAUtil {
105 
106     public static final String RSA = "RSA";
107     
108     public static final String DOTNET_RSA_TRANSFORMATION  = "RSA/ECB/PKCS1Padding";
109 
110     /** 最大文件加密块 */
111     private static final int MAX_ENCRYPT_BLOCK = 117;
112     
113     /** 最大文件解密块 */
114     private static final int MAX_DECRYPT_BLOCK = 128;
115     
116     /**
117      * 获取密钥对
118      * @return
119      */
120     public static KeyPair getKeyPair() {
121         return Encryptor.getKeyPair(RSA, 1024);
122     }
123 
124     /**
125      * Generates the keys for given size.
126      * 
127      * @param size Key Size [512|1024]
128      */
129     public static KeyPair getKeyPair(int size) {
130         return Encryptor.getKeyPair(RSA, size);
131     }
132 
133     private static RSAPrivateCrtKey getRSAPrivateCrtKey(byte[] encodedPrivateKey) {
134         try {
135             EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
136             KeyFactory keyFactory = KeyFactory.getInstance(RSA);
137             return (RSAPrivateCrtKey) keyFactory.generatePrivate(keySpec);
138         } catch (Exception e) {
139             throw new GboatSecurityException("获取 RSA 私钥实例失败。encodedPrivateKey=" + Base64.encodeBase64String(encodedPrivateKey), e);
140         }
141     }
142     
143     /**
144      * 根据私钥字符串,获取对应的私钥实例对象
145      * @param privateKeyStr  经过  BASE64 编码后的私钥字符串
146      * @return
147      */
148     public static PrivateKey getPrivateKey(String privateKeyStr) {
149         byte[] privateKeyBytes = Base64.decodeBase64(privateKeyStr);
150         return getRSAPrivateCrtKey(privateKeyBytes);
151     }
152     
153     /**
154      * 获取私钥
155      * @param privateKeySpec RSA 专用私钥
156      * @return
157      */
158     public static PrivateKey getPrivateKey(RSAPrivateKeySpec privateKeySpec) {
159         try {
160             KeyFactory keyFactory = KeyFactory.getInstance(RSA);
161             return keyFactory.generatePrivate(privateKeySpec);
162         } catch (Exception e) {
163             throw new GboatSecurityException("获取 RSA 私钥实例失败。privateKeySpec=" + privateKeySpec, e);
164         }
165     }
166     
167     /**
168      * 获取私钥
169      * @param base64Modulus the modulus n
170      * @param base64PublicExponent the public exponent e
171      * @param base64PrivateExponent the private exponent d
172      * @param base64PrimeP the prime factor p of n
173      * @param base64PrimeQ the prime factor q of n
174      * @param base64PrimeExponentP this is d mod (p-1)
175      * @param base64PrimeExponentQ this is d mod (q-1)
176      * @param base64CrtCoefficient the Chinese Remainder Theorem coefficient q-1 mod p
177      * @return
178      */
179     public static PrivateKey getPrivateKey(String base64Modulus,
180             String base64PublicExponent, String base64PrivateExponent,
181             String base64PrimeP, String base64PrimeQ,
182             String base64PrimeExponentP, String base64PrimeExponentQ,
183             String base64CrtCoefficient) {
184         BigInteger modulus = new BigInteger(1, Base64.decodeBase64(base64Modulus));
185         BigInteger publicExponent = new BigInteger(1, Base64.decodeBase64(base64PublicExponent));
186         BigInteger privateExponent = new BigInteger(1, Base64.decodeBase64(base64PrivateExponent));
187         BigInteger primeP = new BigInteger(1, Base64.decodeBase64(base64PrimeP));
188         BigInteger primeQ = new BigInteger(1, Base64.decodeBase64(base64PrimeQ));
189         BigInteger primeExponentP = new BigInteger(1, Base64.decodeBase64(base64PrimeExponentP));
190         BigInteger primeExponentQ = new BigInteger(1, Base64.decodeBase64(base64PrimeExponentQ));
191         BigInteger crtCoefficient = new BigInteger(1, Base64.decodeBase64(base64CrtCoefficient));
192         RSAPrivateCrtKeySpec privateKeySpec = new RSAPrivateCrtKeySpec(modulus,
193                 publicExponent, privateExponent, primeP, primeQ,
194                 primeExponentP, primeExponentQ, crtCoefficient);
195         return getPrivateKey(privateKeySpec);
196     }
197 
198     /**
199      * 根据 .NET 的私钥字符串,获取对应的私钥实例对象
200      * @param dotnetRsaParameters  .NET 平台 <a href=
201      *            "http://msdn.microsoft.com/zh-cn/library/system.security.cryptography.rsaparameters(v=vs.110).aspx"
202      *            target="_blank">RSAParameters</a> 相对应的 XML,格式为:
203      * <pre>
204      * <code>
205      * &lt;RSAKeyValue&gt;
206      *   &lt;Modulus&gt;n -&gt; modulus&lt;/Modulus&gt;
207      *   &lt;Exponent&gt;e,公钥指数 -&gt; publicExponent&lt;/Exponent&gt;
208      *   &lt;P&gt;p -&gt; prime1&lt;/P&gt;
209      *   &lt;Q&gt;q -&gt; prime2&lt;/Q&gt;
210      *   &lt;DP&gt;d mod (p - 1) -&gt; exponent1&lt;/DP&gt;
211      *   &lt;DQ&gt;d mod (q - 1) -&gt; exponent2&lt;/DQ&gt;
212      *   &lt;InverseQ&gt;(InverseQ)(q) = 1 mod p -&gt; coefficient&lt;/InverseQ&gt;
213      *   &lt;D&gt;d,私钥指数 -&gt; privateExponent&lt;/D&gt;
214      * &lt;/RSAKeyValue&gt;
215      * </code>
216      * </pre>
217      * @return 么钥实例
218      */
219     public static PrivateKey getPrivateKeyFromDotNetRSAParameters(String dotnetRsaParameters) {
220         if(StringUtils.isBlank(dotnetRsaParameters))
221             throw new IllegalArgumentException("传入的参数为空");
222         
223         Matcher modulusMatcher = Pattern.compile("<Modulus>(.+)</Modulus>").matcher(dotnetRsaParameters);
224         if(!modulusMatcher.find())
225             throw new IllegalArgumentException("没有发现 <Modulus> 节点,dotnetRsaParameters=" + dotnetRsaParameters);
226         
227         Matcher publicExponentMatcher = Pattern.compile("<Exponent>(.+)</Exponent>").matcher(dotnetRsaParameters);
228         if(!publicExponentMatcher.find())
229             throw new IllegalArgumentException("没有发现 <Exponent> 节点,dotnetRsaParameters=" + dotnetRsaParameters);
230         
231         Matcher privateExponentMatcher = Pattern.compile("<D>(.+)</D>").matcher(dotnetRsaParameters);
232         if(!privateExponentMatcher.find())
233             throw new IllegalArgumentException("没有发现 <D> 节点,dotnetRsaParameters=" + dotnetRsaParameters);
234         
235         Matcher primePMatcher = Pattern.compile("<P>(.+)</P>").matcher(dotnetRsaParameters);
236         if(!primePMatcher.find())
237             throw new IllegalArgumentException("没有发现 <P> 节点,dotnetRsaParameters=" + dotnetRsaParameters);
238      
239         Matcher primeQMatcher = Pattern.compile("<Q>(.+)</Q>").matcher(dotnetRsaParameters);
240         if(!primeQMatcher.find())
241             throw new IllegalArgumentException("没有发现 <Q> 节点,dotnetRsaParameters=" + dotnetRsaParameters);
242         
243         Matcher primeExponentPMatcher = Pattern.compile("<DP>(.+)</DP>").matcher(dotnetRsaParameters);
244         if(!primeExponentPMatcher.find())
245             throw new IllegalArgumentException("没有发现 <DP> 节点,dotnetRsaParameters=" + dotnetRsaParameters);
246         
247         Matcher primeExponentQMatcher = Pattern.compile("<DQ>(.+)</DQ>").matcher(dotnetRsaParameters);
248         if(!primeExponentQMatcher.find())
249             throw new IllegalArgumentException("没有发现 <DQ> 节点,dotnetRsaParameters=" + dotnetRsaParameters);
250         
251         Matcher crtCoefficientMatcher = Pattern.compile("<InverseQ>(.+)</InverseQ>").matcher(dotnetRsaParameters);
252         if(!crtCoefficientMatcher.find())
253             throw new IllegalArgumentException("没有发现 <InverseQ> 节点,dotnetRsaParameters=" + dotnetRsaParameters);
254 
255         return getPrivateKey(modulusMatcher.group(1),
256                 publicExponentMatcher.group(1),
257                 privateExponentMatcher.group(1), primePMatcher.group(1),
258                 primeQMatcher.group(1), primeExponentPMatcher.group(1),
259                 primeExponentQMatcher.group(1), crtCoefficientMatcher.group(1));
260     }
261 
262     /**
263      * Returns XML encoded RSA private key string suitable for .NET:CryptoServiceProvider.FromXmlString(true)。
264      * Leading zero bytes (most significant) must be removed for XML encoding for .NET; otherwise format error
265      * @param privateKey 私钥
266      * @return
267      */
268     public static String getDotNetRSAParametersWithPrivateKey(PrivateKey privateKey) {
269         RSAPrivateCrtKey privateCrtKey = (privateKey instanceof RSAPrivateCrtKey) ? (RSAPrivateCrtKey) privateKey
270                 : getRSAPrivateCrtKey(privateKey.getEncoded());
271         StringBuffer buff = new StringBuffer(1024);
272         buff.append("<RSAKeyValue>");
273         buff.append("<Modulus>" + Base64.encodeBase64String(removeMSZero(privateCrtKey.getModulus().toByteArray())) + "</Modulus>");
274         buff.append("<Exponent>" + Base64.encodeBase64String(removeMSZero(privateCrtKey.getPublicExponent().toByteArray())) + "</Exponent>");
275         buff.append("<P>" + Base64.encodeBase64String(removeMSZero(privateCrtKey.getPrimeP().toByteArray())) + "</P>");
276         buff.append("<Q>" + Base64.encodeBase64String(removeMSZero(privateCrtKey.getPrimeQ().toByteArray())) + "</Q>");
277         buff.append("<DP>" + Base64.encodeBase64String(removeMSZero(privateCrtKey.getPrimeExponentP().toByteArray())) + "</DP>");
278         buff.append("<DQ>" + Base64.encodeBase64String(removeMSZero(privateCrtKey.getPrimeExponentQ().toByteArray())) + "</DQ>");
279         buff.append("<InverseQ>" + Base64.encodeBase64String(removeMSZero(privateCrtKey.getCrtCoefficient().toByteArray())) + "</InverseQ>");
280         buff.append("<D>" + Base64.encodeBase64String(removeMSZero(privateCrtKey.getPrivateExponent().toByteArray())) + "</D>");
281         buff.append("</RSAKeyValue>");
282         return buff.toString().replaceAll("[ \t\n\r]", "");
283     }
284 
285     /**
286      * 根据公钥字符串,获取对应的公钥实例对象
287      * @param publicKeyStr  经过  BASE64 编码后的公钥字符串
288      */
289     public static PublicKey getPublicKey(String publicKeyStr) {
290         try {
291             byte[] publicKeyBytes = Base64.decodeBase64(publicKeyStr);
292             KeyFactory keyFactory = KeyFactory.getInstance(RSA);
293             EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes);
294             return keyFactory.generatePublic(publicKeySpec);
295         } catch (Exception e) {
296             throw new GboatSecurityException("获取 RSA 公钥实例失败。publicKeyStr=" + publicKeyStr, e);
297         }
298     }
299     
300     /**
301      * 根据公钥 n、e 生成公钥
302      * 
303      * @param base64Modulus 经过 BASE64 编码的公钥 n 串
304      * @param base64PublicExponent 经过 BASE64 编码的公钥 e 串
305      * @return 公钥实例
306      */
307     public static PublicKey getPublicKey(String base64Modulus, String base64PublicExponent) {
308         BigInteger modulus=new BigInteger(1, Base64.decodeBase64(base64Modulus));
309         BigInteger publicExponent = new BigInteger(1, Base64.decodeBase64(base64PublicExponent));
310         RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(modulus, publicExponent);
311         return getPublicKey(publicKeySpec);
312     }
313 
314     /**
315      * 获取公钥
316      * @param publicKeySpec
317      * @return
318      */
319     public static PublicKey getPublicKey(RSAPublicKeySpec publicKeySpec) {
320         try {
321             KeyFactory keyFactory = KeyFactory.getInstance(RSA);
322             return keyFactory.generatePublic(publicKeySpec);
323         } catch (Exception e) {
324             throw new GboatSecurityException("获取 RSA 私钥实例失败。privateKeySpec=" + publicKeySpec, e);
325         }
326     }
327 
328     /**
329      * 根据 .NET 的私钥字符串,获取对应的私钥实例对象
330      * 
331      * @param dotnetRsaParameters .NET 平台 <a href=
332      *            "http://msdn.microsoft.com/zh-cn/library/system.security.cryptography.rsaparameters(v=vs.110).aspx"
333      *            target="_blank">RSAParameters</a> 相对应的 XML,格式为:
334      * <pre>
335      * <code>
336      * &lt;RSAKeyValue&gt;
337      *     &lt;Modulus&gt;经过 BASE64 编码后的 Modulus&lt;/Modulus&gt;
338      *     &lt;Exponent&gt;经过 BASE64 编码后的 Exponent&lt;/Exponent&gt;
339      * &lt;/RSAKeyValue&gt;
340      * </code>
341      * </pre>
342      * @return
343      */
344     public static PublicKey getPublicKeyFromDotNetRSAParameters(String dotnetRsaParameters) {
345         if(StringUtils.isBlank(dotnetRsaParameters))
346             throw new IllegalArgumentException("传入的参数为空");
347         
348         Matcher modulusMatcher = Pattern.compile("<Modulus>(.+)</Modulus>").matcher(dotnetRsaParameters);
349         if(!modulusMatcher.find())
350             throw new IllegalArgumentException("没有发现 <Modulus> 节点,dotnetRsaParameters=" + dotnetRsaParameters);
351         
352         Matcher exponentMatcher = Pattern.compile("<Exponent>(.+)</Exponent>").matcher(dotnetRsaParameters);
353         if(!exponentMatcher.find())
354             throw new IllegalArgumentException("没有发现 <Exponent> 节点,dotnetRsaParameters=" + dotnetRsaParameters);
355         
356         return getPublicKey(modulusMatcher.group(1), exponentMatcher.group(1));
357     }
358 
359     /**
360      * Returns XML encoded RSA public key string suitable for
361      * .NET:CryptoServiceProvider.FromXmlString(true) Leading zero bytes (most
362      * significant) must be removed for XML encoding for .NET; otherwise format
363      * error
364      * 
365      * @param privateCrtKey
366      * @return 返回结果的格式:
367      * <pre><code>
368      * &lt;RSAKeyValue&gt;
369      *     &lt;Modulus&gt;经过 BASE64 编码后的 Modulus&lt;/Modulus&gt;
370      *     &lt;Exponent&gt;经过 BASE64 编码后的 Exponent&lt;/Exponent&gt;
371      * &lt;/RSAKeyValue&gt;
372      * </code></pre>
373      */
374     public static String getDotNetRSAParametersWithPublicKey(PrivateKey privateKey) {
375         RSAPrivateCrtKey privateCrtKey = (privateKey instanceof RSAPrivateCrtKey) ? (RSAPrivateCrtKey) privateKey
376                 : getRSAPrivateCrtKey(privateKey.getEncoded());
377         byte[] msModulus = removeMSZero(privateCrtKey.getModulus().toByteArray());
378         byte[] msPublicExponent = removeMSZero(privateCrtKey.getPublicExponent().toByteArray());
379         StringBuffer buff = new StringBuffer(1024);
380         buff.append("<RSAKeyValue>");
381         buff.append("<Modulus>" + Base64.encodeBase64String(msModulus) + "</Modulus>");
382         buff.append("<Exponent>" + Base64.encodeBase64String(msPublicExponent) + "</Exponent>");
383         buff.append("</RSAKeyValue>");
384         return buff.toString().replaceAll("[ \t\n\r]", "");
385     }
386 
387     /**
388      * Gets the RSA Public Key. The key idea is to make the key readable for
389      * .Net platform.
390      * 
391      * @param publicKey RSAPublicKey
392      * @return String the public key that .Net platform can read. return format is:
393      * <pre><code>
394      * modules : xxx
395      * exponent : xxx
396      * </code></pre>
397      */
398     public static String getRSAPublicKeyAsNetFormat(RSAPublicKey publicKey) {
399         byte[] msModulus = stripLeadingZeros(publicKey.getModulus().toByteArray());
400         byte[] msPublicExponent = publicKey.getPublicExponent().toByteArray();
401         return "modules : " + Base64.encodeBase64String(msModulus) + "\r\n" + "exponent : " + Base64.encodeBase64String(msPublicExponent);
402     }
403     
404     /**
405      * 对数据进行加密
406      * 
407      * @param data 要进行加密的明文数据
408      * @param key 密钥
409      * @return 加密后的密文
410      */
411     public static byte[] encrypt(byte[] data, Key key) {
412         return encrypt(data, key, key.getAlgorithm());
413     }
414     
415     /**
416      * 对数据进行加密
417      * 
418      * @param data 要进行加密的明文数据
419      * @param key 密钥
420      * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
421      *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
422      *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
423      *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
424      * @return 加密后的密文
425      */
426     public static byte[] encrypt(byte[] data, Key key, String transformation){
427         ByteArrayOutputStream out = null;
428         try {
429             Cipher cipher = Cipher.getInstance(transformation);
430             cipher.init(Cipher.ENCRYPT_MODE, key);
431             out = new ByteArrayOutputStream();
432             int offSet = 0;
433             byte[] cache;
434             while (offSet < data.length) {  // 对数据分段加密
435                 cache = cipher.doFinal(data, offSet, Math.min(data.length - offSet, MAX_ENCRYPT_BLOCK));
436                 out.write(cache);
437                 offSet += MAX_ENCRYPT_BLOCK;
438             }
439             return out.toByteArray();
440         } catch (Exception e) {
441             throw new GboatSecurityException("使用密钥 [" + key + "] 对数据进行加密失败。transformation=" + transformation, e);
442         }finally {
443             IOUtils.closeQuietly(out);
444         }
445     } 
446     
447     /**
448      * 对字符串进行加密
449      * 
450      * @param data 要进行加密的明文字符串
451      * @param key 密钥
452      * @return 加密后的密文
453      */
454     public static byte[] encrypt(String data, Key key) {  
455         return encrypt(data, key, key.getAlgorithm());
456     }
457     
458     /**
459      * 对字符串进行加密
460      * 
461      * @param data 要进行加密的明文字符串
462      * @param key 密钥
463      * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
464      *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
465      *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
466      *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
467      * @return 加密后的密文
468      */
469     public static byte[] encrypt(String data, Key key, String transformation) {
470         return encrypt(data.getBytes(), key, transformation);
471     }
472 
473     /**
474      * 对文件内容进行加密,文件太大可能会导致内存溢出
475      * 
476      * @param data 要进行加密的文件
477      * @param key 密钥
478      * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
479      *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
480      *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
481      *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
482      * @return 加密后的密文
483      * @see #encrypt(File, File, Key)
484      */
485     public static byte[] encrypt(File file, Key key) {
486         return encrypt(file, key, key.getAlgorithm());
487     }
488     
489     /**
490      * 对文件内容进行加密,文件太大可能会导致内存溢出
491      * 
492      * @param data 要进行加密的文件
493      * @param key 密钥
494      * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
495      *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
496      *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
497      *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
498      * @return 加密后的密文
499      * @see #encrypt(File, File, Key, String)
500      */
501     public static byte[] encrypt(File file, Key key, String transformation) {
502         try {
503             return encrypt(FileUtils.readFileToByteArray(file), key, transformation);
504         } catch (IOException e) {
505             throw new GboatSecurityException("对文件加密失败。file=[" + file + "], key=["
506                     + key + "], transformation=[" + transformation + "]", e);
507         }
508     }
509     
510     /**
511      * 对文件进行加密
512      * @param src 源文件
513      * @param dest 加密后文件
514      * @param key 密钥
515      */
516     public static void encrypt(File src, File dest, Key key){
517         encrypt(src, dest, key, key.getAlgorithm());
518     }
519     
520     /**
521      * 对文件进行加密
522      * @param src 源文件
523      * @param dest 加密后文件
524      * @param key 密钥
525      * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
526      *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
527      *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
528      *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
529      */
530     public static void encrypt(File src, File dest, Key key, String transformation) {
531         FileInputStream in = null;
532         OutputStream out = null;
533         try {
534             in = new FileInputStream(src);
535      
536             if (!dest.getParentFile().exists()) {
537                 dest.getParentFile().mkdirs();
538             }
539             // dest.createNewFile();
540             out = new FileOutputStream(dest);
541 
542             Cipher cipher = Cipher.getInstance(transformation);
543             cipher.init(Cipher.ENCRYPT_MODE, key);
544             byte[] data = new byte[MAX_ENCRYPT_BLOCK];
545             int len = 0;
546             while ((len = in.read(data)) != -1) {
547                 out.write(cipher.doFinal(data, 0, len));
548                 // out.flush();
549             }
550         } catch (InvalidKeyException e) {
551             throw new GboatSecurityException("对文件加密失败:密钥无效。src=[" + src + "], dest=[" + dest
552                     + "], key=[" + key + "], transformation=[" + transformation + "]", e);
553         } catch (NoSuchAlgorithmException e) {
554             throw new GboatSecurityException("对文件加密失败:算法 不存在,或当前  JDK 不支持该算法。src=[" + src + "], dest=[" + dest
555                     + "], key=[" + key + "], transformation=[" + transformation + "]", e);
556         } catch (FileNotFoundException e) {
557             throw new GboatSecurityException("对文件加密失败:文件不存在。src=[" + src + "], dest=[" + dest
558                     + "], key=[" + key + "], transformation=[" + transformation + "]", e);
559         } catch (Exception e) {
560             throw new GboatSecurityException("对文件加密失败。src=[" + src + "], dest=[" + dest
561                     + "], key=[" + key + "], transformation=[" + transformation + "]", e);
562         } finally {
563             IOUtils.closeQuietly(out);
564             IOUtils.closeQuietly(in);
565         }
566     }
567     
568     private static Key getKeyByKeySpec(KeySpec keySpec) {
569         if (keySpec == null)
570             throw new IllegalArgumentException("传入的 keySpec 为空");
571 
572         if (keySpec instanceof RSAPrivateKeySpec)
573             return getPrivateKey((RSAPrivateKeySpec) keySpec);
574         
575         if (keySpec instanceof RSAPublicKeySpec)
576             return getPublicKey((RSAPublicKeySpec) keySpec);
577         
578         throw new GboatSecurityException("不支持的密钥规范类型:" + keySpec.getClass().getName() + "。本方法只支持 "
579                 + RSAPrivateKeySpec.class.getName() + " 和 " + RSAPublicKeySpec.class.getName());
580     }
581     
582     /**
583     * 对数据进行加密
584     * 
585     * @param data 要进行加密的明文数据
586     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
587     * @return 加密后的密文
588     */
589    public static byte[] encrypt(byte[] data, KeySpec keySpec) {
590        return encrypt(data, keySpec, RSA);
591    }
592    
593    /**
594     * 对数据进行加密
595     * 
596     * @param data 要进行加密的明文数据
597     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
598     * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
599     *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
600     *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
601     *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
602     * @return 加密后的密文
603     */
604    public static byte[] encrypt(byte[] data, KeySpec keySpec, String transformation){
605        return encrypt(data, getKeyByKeySpec(keySpec), transformation);
606    } 
607    
608    /**
609     * 对字符串进行加密
610     * 
611     * @param data 要进行加密的明文字符串
612     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
613     * @return 加密后的密文
614     */
615    public static byte[] encrypt(String data, KeySpec keySpec) {  
616        return encrypt(data, keySpec, RSA);
617    }
618    
619    /**
620     * 对字符串进行加密
621     * 
622     * @param data 要进行加密的明文字符串
623     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
624     * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
625     *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
626     *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
627     *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
628     * @return 加密后的密文
629     */
630    public static byte[] encrypt(String data, KeySpec keySpec, String transformation) {
631        return encrypt(data, getKeyByKeySpec(keySpec), transformation);
632    }
633 
634    /**
635     * 对文件内容进行加密,文件太大可能会导致内存溢出
636     * 
637     * @param data 要进行加密的文件
638     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
639     * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
640     *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
641     *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
642     *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
643     * @return 加密后的密文
644     * @see #encrypt(File, File, String)
645     */
646    public static byte[] encrypt(File file, KeySpec keySpec) {
647        return encrypt(file, keySpec, RSA);
648    }
649    
650    /**
651     * 对文件内容进行加密,文件太大可能会导致内存溢出
652     * 
653     * @param data 要进行加密的文件
654     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
655     * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
656     *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
657     *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
658     *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
659     * @return 加密后的密文
660     * @see #encrypt(File, File, String, String)
661     */
662    public static byte[] encrypt(File file, KeySpec keySpec, String transformation) {
663        return encrypt(file, getKeyByKeySpec(keySpec), transformation);
664    }
665    
666    /**
667     * 对文件进行加密
668     * @param src 源文件
669     * @param dest 加密后文件
670     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
671     */
672    public static void encrypt(File src, File dest, KeySpec keySpec){
673        encrypt(src, dest, keySpec, RSA);
674    }
675    
676    /**
677     * 对文件进行加密
678     * @param src 源文件
679     * @param dest 加密后文件
680     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
681     * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
682     *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
683     *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
684     *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
685     */
686    public static void encrypt(File src, File dest, KeySpec keySpec, String transformation) {
687        encrypt(src, dest, getKeyByKeySpec(keySpec), transformation);
688    }
689    
690    /**
691    * 使用私钥对数据进行加密
692    * 
693    * @param data 要进行加密的明文数据
694    * @param privateKey 私钥
695    * @return 加密后的密文
696    */
697   public static byte[] encryptByPrivateKey(byte[] data, String privateKey) {
698       return encryptByPrivateKey(data, privateKey, RSA);
699   }
700   
701   /**
702    * 使用私钥对数据进行加密
703    * 
704    * @param data 要进行加密的明文数据
705    * @param privateKey 私钥
706    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
707    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
708    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
709    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
710    * @return 加密后的密文
711    */
712   public static byte[] encryptByPrivateKey(byte[] data, String privateKey, String transformation) {
713       return encrypt(data, getPrivateKey(privateKey), transformation);
714   }
715   
716   /**
717    * 对字符串进行加密
718    * 
719    * @param data 要进行加密的明文字符串
720    * @param privateKey 私钥
721    * @return 加密后的密文
722    */
723   public static byte[] encryptByPrivateKey(String data, String privateKey) {  
724       return encryptByPrivateKey(data, privateKey, RSA);
725   }
726   
727   /**
728    * 对字符串进行加密
729    * 
730    * @param data 要进行加密的明文字符串
731    * @param privateKey 私钥
732    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
733    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
734    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
735    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
736    * @return 加密后的密文
737    */
738   public static byte[] encryptByPrivateKey(String data, String privateKey, String transformation) {
739       return encrypt(data, getPrivateKey(privateKey), transformation);
740   }
741 
742   /**
743    * 对文件内容进行加密,文件太大可能会导致内存溢出
744    * 
745    * @param data 要进行加密的文件
746    * @param privateKey 私钥
747    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
748    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
749    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
750    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
751    * @return 加密后的密文
752    * @see #encryptByPrivateKey(File, File, String)
753    */
754   public static byte[] encryptByPrivateKey(File file, String privateKey) {
755       return encryptByPrivateKey(file, privateKey, RSA);
756   }
757   
758   /**
759    * 对文件内容进行加密,文件太大可能会导致内存溢出
760    * 
761    * @param data 要进行加密的文件
762    * @param privateKey 私钥
763    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
764    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
765    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
766    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
767    * @return 加密后的密文
768    * @see #encryptByPrivateKey(File, File, String, String)
769    */
770   public static byte[] encryptByPrivateKey(File file, String privateKey, String transformation) {
771       return encrypt(file, getPrivateKey(privateKey), transformation);
772   }
773   
774   /**
775    * 对文件进行加密
776    * @param src 源文件
777    * @param dest 加密后文件
778    * @param privateKey 私钥
779    */
780   public static void encryptByPrivateKey(File src, File dest, String privateKey){
781       encryptByPrivateKey(src, dest, privateKey, RSA);
782   }
783   
784   /**
785    * 对文件进行加密
786    * @param src 源文件
787    * @param dest 加密后文件
788    * @param privateKey 私钥
789    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
790    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
791    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
792    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
793    */
794   public static void encryptByPrivateKey(File src, File dest, String privateKey, String transformation) {
795       encrypt(src, dest, getPrivateKey(privateKey), transformation);
796   }
797 
798   /**
799   * 使用公钥对数据进行加密
800   * 
801   * @param data 要进行加密的明文数据
802   * @param publicKey 公钥
803   * @return 加密后的密文
804   */
805   public static byte[] encryptByPublicKey(byte[] data, String publicKey) {
806       return encryptByPublicKey(data, publicKey, RSA);
807   }
808  
809  /**
810   * 使用公钥对数据进行加密
811   * 
812   * @param data 要进行加密的明文数据
813   * @param publicKey 公钥
814   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
815   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
816   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
817   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
818   * @return 加密后的密文
819   */
820   public static byte[] encryptByPublicKey(byte[] data, String publicKey, String transformation){
821       return encrypt(data, getPublicKey(publicKey), transformation);
822   }
823  
824  /**
825   * 对字符串进行加密
826   * 
827   * @param data 要进行加密的明文字符串
828   * @param publicKey 公钥
829   * @return 加密后的密文
830   */
831   public static byte[] encryptByPublicKey(String data, String publicKey) {  
832       return encryptByPublicKey(data, publicKey, RSA);
833   }
834  
835  /**
836   * 对字符串进行加密
837   * 
838   * @param data 要进行加密的明文字符串
839   * @param publicKey 公钥
840   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
841   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
842   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
843   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
844   * @return 加密后的密文
845   */
846   public static byte[] encryptByPublicKey(String data, String publicKey, String transformation) {
847       return encrypt(data, getPublicKey(publicKey), transformation);
848   }
849 
850  /**
851   * 对文件内容进行加密,文件太大可能会导致内存溢出
852   * 
853   * @param data 要进行加密的文件
854   * @param publicKey 公钥
855   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
856   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
857   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
858   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
859   * @return 加密后的密文
860   * @see #encryptByPublicKey(File, File, String)
861   */
862   public static byte[] encryptByPublicKey(File file, String publicKey) {
863       return encryptByPublicKey(file, publicKey, RSA);
864   }
865  
866  /**
867   * 对文件内容进行加密,文件太大可能会导致内存溢出
868   * 
869   * @param data 要进行加密的文件
870   * @param publicKey 公钥
871   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
872   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
873   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
874   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
875   * @return 加密后的密文
876   * @see #encryptByPublicKey(File, File, String, String)
877   */
878   public static byte[] encryptByPublicKey(File file, String publicKey, String transformation) {
879       return encrypt(file, getPublicKey(publicKey), transformation);
880   }
881  
882  /**
883   * 对文件进行加密
884   * @param src 源文件
885   * @param dest 加密后文件
886   * @param publicKey 公钥
887   */
888   public static void encryptByPublicKey(File src, File dest, String publicKey){
889       encryptByPublicKey(src, dest, publicKey, RSA);
890   }
891  
892  /**
893   * 对文件进行加密
894   * @param src 源文件
895   * @param dest 加密后文件
896   * @param publicKey 公钥
897   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
898   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
899   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
900   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
901   */
902   public static void encryptByPublicKey(File src, File dest, String publicKey, String transformation) {
903       encrypt(src, dest, getPublicKey(publicKey), transformation);
904   }
905 
906  /**
907    * 对数据进行加密
908    * 
909    * @param data 要进行加密的明文数据
910    * @param key 密钥
911    * @return 加密后的密文
912    */
913   public static String encryptBase64(byte[] data, Key key) {
914       return encryptBase64(data, key, key.getAlgorithm());
915   }
916   
917   /**
918    * 对数据进行加密
919    * 
920    * @param data 要进行加密的明文数据
921    * @param key 密钥
922    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
923    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
924    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
925    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
926    * @return 加密后的密文
927    */
928   public static String encryptBase64(byte[] data, Key key, String transformation){
929       byte[] result = encrypt(data, key, transformation);
930       return Base64.encodeBase64String(result);
931   } 
932   
933   /**
934    * 对字符串进行加密
935    * 
936    * @param data 要进行加密的明文字符串
937    * @param key 密钥
938    * @return 加密后的密文
939    */
940   public static String encryptBase64(String data, Key key) {  
941       return encryptBase64(data, key, key.getAlgorithm());
942   }
943   
944   /**
945    * 对字符串进行加密
946    * 
947    * @param data 要进行加密的明文字符串
948    * @param key 密钥
949    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
950    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
951    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
952    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
953    * @return 加密后的密文
954    */
955   public static String encryptBase64(String data, Key key, String transformation) {
956       return encryptBase64(data.getBytes(), key, transformation);
957   }
958   /**
959   * 对数据进行加密
960   * 
961   * @param data 要进行加密的明文数据
962   * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
963   * @return 加密后的密文
964   */
965   public static String encryptBase64(byte[] data, KeySpec keySpec) {
966       return encryptBase64(data, keySpec, RSA);
967   }
968  
969  /**
970   * 对数据进行加密
971   * 
972   * @param data 要进行加密的明文数据
973   * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
974   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
975   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
976   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
977   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
978   * @return 加密后的密文
979   */
980   public static String encryptBase64(byte[] data, KeySpec keySpec, String transformation){
981       return encryptBase64(data, getKeyByKeySpec(keySpec), RSA);
982   } 
983  
984  /**
985   * 对字符串进行加密
986   * 
987   * @param data 要进行加密的明文字符串
988   * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
989   * @return 加密后的密文
990   */
991   public static String encryptBase64(String data, KeySpec keySpec) {  
992       return encryptBase64(data, keySpec, RSA);
993   }
994  
995  /**
996   * 对字符串进行加密
997   * 
998   * @param data 要进行加密的明文字符串
999   * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
1000   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1001   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1002   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1003   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1004   * @return 加密后的密文
1005   */
1006   public static String encryptBase64(String data, KeySpec keySpec, String transformation) {
1007       return encryptBase64(data, getKeyByKeySpec(keySpec), RSA);
1008   }
1009 
1010  /**
1011  * 使用私钥对数据进行加密
1012  * 
1013  * @param data 要进行加密的明文数据
1014  * @param privateKey 私钥
1015  * @return 加密后的密文
1016  */
1017   public static String encryptBase64ByPrivateKey(byte[] data, String privateKey) {
1018       return encryptBase64ByPrivateKey(data, privateKey, RSA);
1019   }
1020 
1021   /**
1022    * 使用私钥对数据进行加密
1023    * 
1024    * @param data 要进行加密的明文数据
1025    * @param privateKey 私钥
1026    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1027    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1028    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1029    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1030    * @return 加密后的密文
1031    */
1032   public static String encryptBase64ByPrivateKey(byte[] data, String privateKey, String transformation){
1033       return encryptBase64(data, getPrivateKey(privateKey), RSA);
1034   } 
1035 
1036   /**
1037    * 使用私钥对字符串进行加密
1038    * 
1039    * @param data 要进行加密的明文字符串
1040    * @param privateKey 私钥
1041    * @return 加密后的密文
1042    */
1043   public static String encryptBase64ByPrivateKey(String data, String privateKey) {  
1044       return encryptBase64ByPrivateKey(data, privateKey, RSA);
1045   }
1046 
1047   /**
1048    * 使用私钥对字符串进行加密
1049    * 
1050    * @param data 要进行加密的明文字符串
1051    * @param privateKey 私钥
1052    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1053    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1054    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1055    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1056    * @return 加密后的密文
1057    */
1058   public static String encryptBase64ByPrivateKey(String data, String privateKey, String transformation) {
1059       return encryptBase64(data, getPrivateKey(privateKey), RSA);
1060   }
1061 
1062   /**
1063   * 使用公钥对数据进行加密
1064   * 
1065   * @param data 要进行加密的明文数据
1066   * @param publicKey 公钥
1067   * @return 加密后的密文
1068   */
1069   public static String encryptBase64ByPublicKey(byte[] data, String publicKey) {
1070      return encryptBase64ByPublicKey(data, publicKey, RSA);
1071   }
1072 
1073   /**
1074   * 使用公钥对数据进行加密
1075   * 
1076   * @param data 要进行加密的明文数据
1077   * @param publicKey 公钥
1078   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1079   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1080   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1081   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1082   * @return 加密后的密文
1083   */
1084   public static String encryptBase64ByPublicKey(byte[] data, String publicKey, String transformation){
1085       return encryptBase64(data, getPublicKey(publicKey), RSA);
1086   } 
1087 
1088   /**
1089   * 使用公钥对字符串进行加密
1090   * 
1091   * @param data 要进行加密的明文字符串
1092   * @param publicKey 公钥
1093   * @return 加密后的密文
1094   */
1095   public static String encryptBase64ByPublicKey(String data, String publicKey) {  
1096      return encryptBase64ByPublicKey(data, publicKey, RSA);
1097   }
1098 
1099   /**
1100   * 使用公钥对字符串进行加密
1101   * 
1102   * @param data 要进行加密的明文字符串
1103   * @param publicKey 公钥
1104   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1105   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1106   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1107   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1108   * @return 加密后的密文
1109   */
1110   public static String encryptBase64ByPublicKey(String data, String publicKey, String transformation) {
1111       return encryptBase64(data, getPublicKey(publicKey), RSA);
1112   }
1113 
1114 
1115 
1116   /**
1117    * 对数据进行解密
1118    * 
1119    * @param data 要进行解密的密文数据
1120    * @param key 密钥
1121    * @return 解密后的密文
1122    */
1123   public static byte[] decrypt(byte[] data, Key key) {
1124       return decrypt(data, key, key.getAlgorithm());
1125   }
1126 
1127     /**
1128      * 对数据进行解密
1129      * 
1130      * @param data 要进行解密的密文
1131      * @param key 密钥
1132      * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1133      *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1134      *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1135      *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1136      * @return 解密后的明文
1137      */
1138       public static byte[] decrypt(byte[] encryptedData, Key key, String transformation) {
1139           ByteArrayOutputStream out = null;
1140           try {
1141               Cipher cipher = Cipher.getInstance(transformation);
1142               cipher.init(Cipher.DECRYPT_MODE, key);
1143               out = new ByteArrayOutputStream();
1144               int offSet = 0;
1145               byte[] cache;
1146               // 对数据分段解密
1147               while (offSet < encryptedData.length) {
1148                   cache = cipher.doFinal(encryptedData, offSet, Math.min(MAX_DECRYPT_BLOCK,
1149                           encryptedData.length - offSet));
1150                   out.write(cache);
1151                   offSet += MAX_DECRYPT_BLOCK;
1152               }
1153               return out.toByteArray();
1154           } catch (Exception e) {
1155               throw new GboatSecurityException("使用密钥 [" + key
1156                       + "] 对数据进行加密失败。transformation=" + transformation, e);
1157           } finally {
1158               IOUtils.closeQuietly(out);
1159           }
1160       }
1161       
1162     /**
1163      * 对字符串进行解密
1164      * 
1165      * @param data 经过 BASE64 编码的的密文字符串
1166      * @param key 密钥
1167      * @return 解密后的密文
1168      */
1169     public static byte[] decrypt(String data, Key key) {  
1170         return decrypt(data, key, key.getAlgorithm());
1171     }
1172     
1173     /**
1174      * 对字符串进行解密
1175      * 
1176      * @param data 经过 BASE64 编码的的密文字符串
1177      * @param key 密钥
1178      * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1179      *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1180      *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1181      *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1182      * @return 解密后的密文
1183      */
1184     public static byte[] decrypt(String data, Key key, String transformation) {
1185         return decrypt(Base64.decodeBase64(data), key, transformation);
1186     }
1187 
1188     /**
1189      * 对文件内容进行解密,文件太大可能会导致内存溢出
1190      * 
1191      * @param data 要进行解密的文件
1192      * @param key 密钥
1193      * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1194      *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1195      *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1196      *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1197      * @return 解密后的密文
1198      * @see #decrypt(File, File, Key)
1199      */
1200     public static byte[] decrypt(File file, Key key) {
1201         return decrypt(file, key, key.getAlgorithm());
1202     }
1203     
1204     /**
1205      * 对文件内容进行解密,文件太大可能会导致内存溢出
1206      * 
1207      * @param data 要进行解密的文件
1208      * @param key 密钥
1209      * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1210      *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1211      *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1212      *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1213      * @return 解密后的密文
1214      * @see #decrypt(File, File, Key, String)
1215      */
1216     public static byte[] decrypt(File file, Key key, String transformation) {
1217         try {
1218             return decrypt(FileUtils.readFileToByteArray(file), key, transformation);
1219         } catch (IOException e) {
1220             throw new GboatSecurityException("对文件解密失败。file=[" + file + "], key=["
1221                     + key + "], transformation=[" + transformation + "]", e);
1222         }
1223     }
1224     
1225     /**
1226      * 对文件进行解密
1227      * @param src 源文件
1228      * @param dest 解密后文件
1229      * @param key 密钥
1230      */
1231     public static void decrypt(File src, File dest, Key key){
1232         decrypt(src, dest, key, key.getAlgorithm());
1233     }
1234 
1235     /**
1236      * 对文件进行解密
1237      * @param src 加密后的文件
1238      * @param dest 解密后的文件
1239      * @param key 密钥
1240      * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1241      *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1242      *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1243      *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1244      */
1245     public static void decrypt(File src, File dest, Key key, String transformation) {
1246         if (!dest.getParentFile().exists()) {
1247             dest.getParentFile().mkdirs();
1248         }
1249 //        dest.createNewFile();
1250         
1251         FileInputStream in = null;
1252         OutputStream out = null;
1253         try {
1254             Cipher cipher = Cipher.getInstance(transformation);
1255             cipher.init(Cipher.DECRYPT_MODE, key);
1256           
1257             in = new FileInputStream(src);
1258             out = new FileOutputStream(dest);
1259             byte[] data = new byte[MAX_DECRYPT_BLOCK];
1260             int len = 0; // 解密块
1261             while ((len = in.read(data)) != -1) {
1262                 out.write(cipher.doFinal(data), 0, len);
1263 //                out.flush();
1264             }
1265         } catch (InvalidKeyException e) {
1266             throw new GboatSecurityException("对文件加密失败:密钥无效。src=[" + src + "], dest=[" + dest
1267                     + "], key=[" + key + "], transformation=[" + transformation + "]", e);
1268         } catch (NoSuchAlgorithmException e) {
1269             throw new GboatSecurityException("对文件加密失败:算法 不存在,或当前  JDK 不支持该算法。src=[" + src + "], dest=[" + dest
1270                     + "], key=[" + key + "], transformation=[" + transformation + "]", e);
1271         } catch (FileNotFoundException e) {
1272             throw new GboatSecurityException("对文件加密失败:文件不存在。src=[" + src + "], dest=[" + dest
1273                     + "], key=[" + key + "], transformation=[" + transformation + "]", e);
1274         } catch (Exception e) {
1275             throw new GboatSecurityException("对文件加密失败。src=[" + src + "], dest=[" + dest
1276                     + "], key=[" + key + "], transformation=[" + transformation + "]", e);
1277         } finally {
1278             IOUtils.closeQuietly(out);
1279             IOUtils.closeQuietly(in);
1280         }
1281     }
1282     
1283     /**
1284     * 对数据进行解密
1285     * 
1286     * @param data 要进行解密的密文数据
1287     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
1288     * @return 解密后的密文
1289     */
1290    public static byte[] decrypt(byte[] data, KeySpec keySpec) {
1291        return decrypt(data, keySpec, RSA);
1292    }
1293    
1294    /**
1295     * 对数据进行解密
1296     * 
1297     * @param data 要进行解密的密文数据
1298     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
1299     * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1300     *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1301     *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1302     *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1303     * @return 解密后的密文
1304     */
1305    public static byte[] decrypt(byte[] data, KeySpec keySpec, String transformation){
1306        return decrypt(data, getKeyByKeySpec(keySpec), transformation);
1307    } 
1308    
1309    /**
1310     * 对字符串进行解密
1311     * 
1312     * @param data 经过 BASE64 编码的的密文字符串
1313     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
1314     * @return 解密后的密文
1315     */
1316    public static byte[] decrypt(String data, KeySpec keySpec) {  
1317        return decrypt(data, keySpec, RSA);
1318    }
1319    
1320    /**
1321     * 对字符串进行解密
1322     * 
1323     * @param data 经过 BASE64 编码的的密文字符串
1324     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
1325     * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1326     *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1327     *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1328     *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1329     * @return 解密后的密文
1330     */
1331    public static byte[] decrypt(String data, KeySpec keySpec, String transformation) {
1332        return decrypt(data, getKeyByKeySpec(keySpec), transformation);
1333    }
1334 
1335    /**
1336     * 对文件内容进行解密,文件太大可能会导致内存溢出
1337     * 
1338     * @param data 要进行解密的文件
1339     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
1340     * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1341     *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1342     *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1343     *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1344     * @return 解密后的密文
1345     * @see #decrypt(File, File, String)
1346     */
1347    public static byte[] decrypt(File file, KeySpec keySpec) {
1348        return decrypt(file, keySpec, RSA);
1349    }
1350    
1351    /**
1352     * 对文件内容进行解密,文件太大可能会导致内存溢出
1353     * 
1354     * @param data 要进行解密的文件
1355     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
1356     * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1357     *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1358     *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1359     *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1360     * @return 解密后的密文
1361     * @see #decrypt(File, File, String, String)
1362     */
1363    public static byte[] decrypt(File file, KeySpec keySpec, String transformation) {
1364        return decrypt(file, getKeyByKeySpec(keySpec), transformation);
1365    }
1366    
1367    /**
1368     * 对文件进行解密
1369     * @param src 源文件
1370     * @param dest 解密后文件
1371     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
1372     */
1373    public static void decrypt(File src, File dest, KeySpec keySpec){
1374        decrypt(src, dest, keySpec, RSA);
1375    }
1376    
1377    /**
1378     * 对文件进行解密
1379     * @param src 源文件
1380     * @param dest 解密后文件
1381     * @param keySpec RSA 专用密钥规范,类型必须是 {@link RSAPrivateKeySpec} 或  {@link RSAPublicKeySpec} 
1382     * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1383     *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1384     *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1385     *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1386     */
1387    public static void decrypt(File src, File dest, KeySpec keySpec, String transformation) {
1388        decrypt(src, dest, getKeyByKeySpec(keySpec), transformation);
1389    }
1390    
1391    /**
1392    * 使用私钥对数据进行解密
1393    * 
1394    * @param data 要进行解密的密文数据
1395    * @param privateKey 私钥
1396    * @return 解密后的密文
1397    */
1398   public static byte[] decryptByPrivateKey(byte[] data, String privateKey) {
1399       return decryptByPrivateKey(data, privateKey, RSA);
1400   }
1401   
1402   /**
1403    * 使用私钥对数据进行解密
1404    * 
1405    * @param data 要进行解密的密文数据
1406    * @param privateKey 私钥
1407    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1408    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1409    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1410    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1411    * @return 解密后的密文
1412    */
1413   public static byte[] decryptByPrivateKey(byte[] data, String privateKey, String transformation) {
1414       return decrypt(data, getPrivateKey(privateKey), transformation);
1415   }
1416   
1417   /**
1418    * 对字符串进行解密
1419    * 
1420    * @param data 经过 BASE64 编码的的密文字符串
1421    * @param privateKey 私钥
1422    * @return 解密后的密文
1423    */
1424   public static byte[] decryptByPrivateKey(String data, String privateKey) {  
1425       return decryptByPrivateKey(data, privateKey, RSA);
1426   }
1427   
1428   /**
1429    * 对字符串进行解密
1430    * 
1431    * @param data 经过 BASE64 编码的的密文字符串
1432    * @param privateKey 私钥
1433    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1434    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1435    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1436    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1437    * @return 解密后的密文
1438    */
1439   public static byte[] decryptByPrivateKey(String data, String privateKey, String transformation) {
1440       return decrypt(data, getPrivateKey(privateKey), transformation);
1441   }
1442 
1443   /**
1444    * 对文件内容进行解密,文件太大可能会导致内存溢出
1445    * 
1446    * @param data 要进行解密的文件
1447    * @param privateKey 私钥
1448    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1449    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1450    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1451    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1452    * @return 解密后的密文
1453    * @see #decryptByPrivateKey(File, File, String)
1454    */
1455   public static byte[] decryptByPrivateKey(File file, String privateKey) {
1456       return decryptByPrivateKey(file, privateKey, RSA);
1457   }
1458   
1459   /**
1460    * 对文件内容进行解密,文件太大可能会导致内存溢出
1461    * 
1462    * @param data 要进行解密的文件
1463    * @param privateKey 私钥
1464    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1465    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1466    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1467    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1468    * @return 解密后的密文
1469    * @see #decryptByPrivateKey(File, File, String, String)
1470    */
1471   public static byte[] decryptByPrivateKey(File file, String privateKey, String transformation) {
1472       return decrypt(file, getPrivateKey(privateKey), transformation);
1473   }
1474   
1475   /**
1476    * 对文件进行解密
1477    * @param src 源文件
1478    * @param dest 解密后文件
1479    * @param privateKey 私钥
1480    */
1481   public static void decryptByPrivateKey(File src, File dest, String privateKey){
1482       decryptByPrivateKey(src, dest, privateKey, RSA);
1483   }
1484   
1485   /**
1486    * 对文件进行解密
1487    * @param src 源文件
1488    * @param dest 解密后文件
1489    * @param privateKey 私钥
1490    * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1491    *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1492    *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1493    *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1494    */
1495   public static void decryptByPrivateKey(File src, File dest, String privateKey, String transformation) {
1496       decrypt(src, dest, getPrivateKey(privateKey), transformation);
1497   }
1498 
1499   /**
1500   * 使用公钥对数据进行解密
1501   * 
1502   * @param data 要进行解密的密文数据
1503   * @param publicKey 公钥
1504   * @return 解密后的密文
1505   */
1506   public static byte[] decryptByPublicKey(byte[] data, String publicKey) {
1507       return decryptByPublicKey(data, publicKey, RSA);
1508   }
1509  
1510  /**
1511   * 使用公钥对数据进行解密
1512   * 
1513   * @param data 要进行解密的密文数据
1514   * @param publicKey 公钥
1515   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1516   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1517   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1518   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1519   * @return 解密后的密文
1520   */
1521   public static byte[] decryptByPublicKey(byte[] data, String publicKey, String transformation){
1522       return decrypt(data, getPublicKey(publicKey), transformation);
1523   }
1524  
1525  /**
1526   * 对字符串进行解密
1527   * 
1528   * @param data 经过 BASE64 编码的的密文字符串
1529   * @param publicKey 公钥
1530   * @return 解密后的密文
1531   */
1532   public static byte[] decryptByPublicKey(String data, String publicKey) {  
1533       return decryptByPublicKey(data, publicKey, RSA);
1534   }
1535  
1536  /**
1537   * 对字符串进行解密
1538   * 
1539   * @param data 经过 BASE64 编码的的密文字符串
1540   * @param publicKey 公钥
1541   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1542   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1543   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1544   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1545   * @return 解密后的密文
1546   */
1547   public static byte[] decryptByPublicKey(String data, String publicKey, String transformation) {
1548       return decrypt(data, getPublicKey(publicKey), transformation);
1549   }
1550 
1551  /**
1552   * 对文件内容进行解密,文件太大可能会导致内存溢出
1553   * 
1554   * @param data 要进行解密的文件
1555   * @param publicKey 公钥
1556   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1557   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1558   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1559   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1560   * @return 解密后的密文
1561   * @see #decryptByPublicKey(File, File, String)
1562   */
1563   public static byte[] decryptByPublicKey(File file, String publicKey) {
1564       return decryptByPublicKey(file, publicKey, RSA);
1565   }
1566  
1567  /**
1568   * 对文件内容进行解密,文件太大可能会导致内存溢出
1569   * 
1570   * @param data 要进行解密的文件
1571   * @param publicKey 公钥
1572   * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1573   *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1574   *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1575   *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1576   * @return 解密后的密文
1577   * @see #decryptByPublicKey(File, File, String, String)
1578   */
1579   public static byte[] decryptByPublicKey(File file, String publicKey, String transformation) {
1580       return decrypt(file, getPublicKey(publicKey), transformation);
1581   }
1582  
1583     /**
1584      * 对文件进行解密
1585      * @param src 源文件
1586      * @param dest 解密后文件
1587      * @param publicKey 公钥
1588      */
1589     public static void decryptByPublicKey(File src, File dest, String publicKey) {
1590         decryptByPublicKey(src, dest, publicKey, RSA);
1591     }
1592  
1593     /**
1594      * 对文件进行解密
1595      * @param src 源文件
1596      * @param dest 解密后文件
1597      * @param publicKey 公钥
1598      * @param transformation  the name of the transformation, format is "Algorithm/Modes/Paddings", e.g.,
1599      *            DES/CBC/PKCS5Padding. See Appendix A in the <a target="_blank"
1600      *            href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#AppA">
1601      *            Java Cryptography Architecture Reference Guide</a> for information about standard transformation names.
1602      */
1603     public static void decryptByPublicKey(File src, File dest, String publicKey, String transformation) {
1604         decrypt(src, dest, getPublicKey(publicKey), transformation);
1605     }
1606 
1607     /**
1608      * remove leading (Most Significant) zero byte if present
1609      * 
1610      * @param data
1611      * @return
1612      */
1613     private static byte[] removeMSZero(byte[] data) {
1614         byte[] data1;
1615         int len = data.length;
1616         if (data[0] == 0) {
1617             data1 = new byte[data.length - 1];
1618             System.arraycopy(data, 1, data1, 0, len - 1);
1619         } else
1620             data1 = data;
1621 
1622         return data1;
1623     }
1624 
1625     /**
1626      * Utility method to delete the leading zeros from the modulus.
1627      * 
1628      * @param modulus
1629      * @return
1630      */
1631     private static byte[] stripLeadingZeros(byte[] modulus) {
1632         int lastZero = -1;
1633         for (int i = 0; i < modulus.length; i++) {
1634             if (modulus[i] == 0) {
1635                 lastZero = i;
1636             } else {
1637                 break;
1638             }
1639         }
1640         lastZero++;
1641         byte[] result = new byte[modulus.length - lastZero];
1642         System.arraycopy(modulus, lastZero, result, 0, result.length);
1643         return result;
1644     }
1645 
1646 }