package com.zcloud.util; import javax.crypto.Cipher; import java.io.ByteArrayOutputStream; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * RSA公钥/私钥/签名工具包 *

* 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式
* 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,
* 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全 *

* */ public class RSAUtils { /** */ /** * 加密算法RSA */ public static final String KEY_ALGORITHM = "RSA"; /** */ /** * 签名算法 */ public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /** */ /** * 获取公钥的key */ private static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUoHAavCikaZxjlDM6Km8cX+ye78F4oF39AcEfnE1p2Yn9pJ9WFxYZ4Vkh6F8SKMi7k4nYsKceqB1RwG996SvHQ5C3pM3nbXCP4K15ad6QhN4a7lzlbLhiJcyIKszvvK8ncUDw8mVQ0j/2mwxv05yH6LN9OKU6Hzm1ninpWeE+awIDAQAB\n"; /** */ /** * 获取私钥的key */ private static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANSgcBq8KKRpnGOUMzoqbxxf7J7vwXigXf0BwR+cTWnZif2kn1YXFhnhWSHoXxIoyLuTidiwpx6oHVHAb33pK8dDkLekzedtcI/grXlp3pCE3hruXOVsuGIlzIgqzO+8rydxQPDyZVDSP/abDG/TnIfos304pTofObWeKelZ4T5rAgMBAAECgYEAt2Dvjn885h+Xm2JTlBTI40Xvw1uwFqLorK54qxSYx3OwySrTqOIcU5HA17ebVwQJq40hU9t3Jr+DGeDHx2X0NEJ0LXuDMzeWxUwUMbdxxM7OXS6Zuhy73C99DyAweLP9K1H2J/y1+eJ4Zx/0mTiAgCKJFNWAQBZwGl5Zu2zoHOECQQDw0UlrOUfloxK3hfVSWlfL7+onP+z/qa9bzemSg676sAJqA8d5ao8V532OBOtZxfPSlh4igC0lpY2vnCRHrwJZAkEA4ggpMS4o+rfFmNslNzI0m3VFDiLYmghYIqTLHtLYqAbY8QVfFd8bl920t5LQAlTsI3q9Spsu8y7AnAWmYydGYwJAN+tBMya/7TDqvbbbel4EGRUCuE59x/gtAhJUdHMjhI6uYNOz1BvMUffJDdtSkywGLBYztSsyUJWayvZk7khTMQJAALM7xW46LESjdQzAucILDaw4UYnkF94Mv9a41lia2TJkO6Ljn4K4aCkEpUjsIgW3UYjQy0ldxN0RNaqC0G3PtwJAFafiLzcls6qzyAlh5PqM5cJrs+Xa0rHR322/AlSyuxW6wRzUX/zSoorP34JCjRPT5DzUeHMVvr6S2BE8k/8XYg=="; /** */ /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** */ /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /** */ /** *

* 生成密钥对(公钥和私钥) *

* * @return * @throws Exception */ public static Map genKeyPair() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map keyMap = new HashMap(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** */ /** *

* 用私钥对信息生成数字签名 *

* * @param data * 已加密数据 * @param privateKey * 私钥(BASE64编码) * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(data); return Base64Utils.encode(signature.sign()); } /** */ /** *

* 校验数字签名 *

* * @param data * 已加密数据 * @param publicKey * 公钥(BASE64编码) * @param sign * 数字签名 * * @return * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicK = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicK); signature.update(data); return signature.verify(Base64Utils.decode(sign)); } /** */ /** *

* 私钥解密 *

* * @param encryptedData * 已加密数据 * @param privateKey * 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** */ /** *

* 公钥解密 *

* * @param encryptedData * 已加密数据 * @param publicKey * 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** */ /** *

* 公钥加密 *

* * @param data * 源数据 * @param publicKey * 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** */ /** *

* 私钥加密 *

* * @param data * 源数据 * @param privateKey * 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** */ /** *

* 获取私钥 *

* * @param keyMap * 密钥对 * @return * @throws Exception */ public static String getPrivateKey(Map keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return Base64Utils.encode(key.getEncoded()); } /** */ /** *

* 获取私钥 *

* * @param keyMap * 密钥对 * @return * @throws Exception */ public static String getPrivateKey() { return PRIVATE_KEY; } /** */ /** *

* 获取公钥 *

* * @param keyMap * 密钥对 * @return * @throws Exception */ public static String getPublicKey(Map keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return Base64Utils.encode(key.getEncoded()); } /** */ /** *

* 获取公钥 *

* @return * @throws Exception */ public static String getPublicKey() throws Exception { return PUBLIC_KEY; } /** * java端公钥加密 */ public static String encryptedDataOnJava(String data, String PUBLICKEY) { try { data = Base64Utils.encode(encryptByPublicKey(data.getBytes(), PUBLICKEY)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return data; } /** * java端私钥解密 */ public static String decryptDataOnJava(String data, String PRIVATEKEY) { String temp = ""; try { byte[] rs = Base64Utils.decode(data); temp = new String(RSAUtils.decryptByPrivateKey(rs, PRIVATEKEY),"UTF-8"); //以utf-8的方式生成字符串 } catch (Exception e) { e.printStackTrace(); } return temp; } public static void main(String[] args) { Map keyMap = null; try { keyMap = RSAUtils.genKeyPair(); String publicKey = RSAUtils.getPublicKey(keyMap); String privateKey = RSAUtils.getPrivateKey(keyMap); System.err.println("公钥: \n\r" + publicKey); System.err.println("私钥: \n\r" + privateKey); // 公钥: // MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDE8aNkz3X5f96bW2EJ3fRQsEmtgrIzLSCSJZLf1WBay0ihEideK45md5UZIFB6HSWwBaKD4z1uAMdt5esn0AIvrQS8+nlnB+Fohzxg7yY2ooDLP2az0WVKzepbeg8igq+jflUh7/+rvndiJAnv+mnMbibFqhYsDAJ3Zq82FkOeXQIDAQAB // 私钥: // MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMTxo2TPdfl/3ptbYQnd9FCwSa2CsjMtIJIlkt/VYFrLSKESJ14rjmZ3lRkgUHodJbAFooPjPW4Ax23l6yfQAi+tBLz6eWcH4WiHPGDvJjaigMs/ZrPRZUrN6lt6DyKCr6N+VSHv/6u+d2IkCe/6acxuJsWqFiwMAndmrzYWQ55dAgMBAAECgYB1gfPKz5oFjw0ERyaEG6GNj1G2rFek/1UCvlZ/JTJDmi0wpcNFhdmGO+2DO2upIMD+4K3R4YEipGZZpSiE7bCPM1uIerVAi0efTQMZKSrreud29Z/6xN0166GthAj30AjrwxfNAhoUNQXcG2NQJmfUpPlV95Cjh2b6tTlLdU9foQJBAO2zrzYeLiBrhEOZqr5JC8zUdseGSKCwIvZDwQ+s8GuuSVpm1q9mHOL3TODNlawfst78o9QBkk2MyKP7Voe6C6UCQQDUGr/A7XTvV39fqO4V+BcSLDCpxTHJ8UUWiRovXhDMn0TjqeRnDiRC9YuMf5XCXwDkYnK/u3O2maZugrcgUqpZAkBgd4zC9MqZg6jg2mtN4E02qn8uCFRPSkxWDzc5ymCkAs5oLtYvxswwXFbJ4QU+Hns0Pemq75xVdq4yxpzeZmW1AkEAvOi+FJTpaypg9dA9jS+TTMoy5WIOgC/1OqcNvVZoW/cWojZ0iRzdSw3rJk2UErQO1VqhnQbVfrLGuvKNK6q0sQJATbmrgK1KDaAS3Ns8MI6pDKWWHaAy8Vrnwz4nRIX2C0FKLTYwbNPrvVHdpD0ItZ8p9wiAL6HVn5ipxbz6v0l1uA== } catch (Exception e) { e.printStackTrace(); } } }