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 * <RSAKeyValue> 206 * <Modulus>n -> modulus</Modulus> 207 * <Exponent>e,公钥指数 -> publicExponent</Exponent> 208 * <P>p -> prime1</P> 209 * <Q>q -> prime2</Q> 210 * <DP>d mod (p - 1) -> exponent1</DP> 211 * <DQ>d mod (q - 1) -> exponent2</DQ> 212 * <InverseQ>(InverseQ)(q) = 1 mod p -> coefficient</InverseQ> 213 * <D>d,私钥指数 -> privateExponent</D> 214 * </RSAKeyValue> 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 * <RSAKeyValue> 337 * <Modulus>经过 BASE64 编码后的 Modulus</Modulus> 338 * <Exponent>经过 BASE64 编码后的 Exponent</Exponent> 339 * </RSAKeyValue> 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 * <RSAKeyValue> 369 * <Modulus>经过 BASE64 编码后的 Modulus</Modulus> 370 * <Exponent>经过 BASE64 编码后的 Exponent</Exponent> 371 * </RSAKeyValue> 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 }