package cn.wisenergy.common.utils; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import javax.crypto.Cipher; import org.apache.commons.codec.binary.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.springframework.util.Assert; /** * Utils - RSA加密解密 * * @version 3.0 */ public final class RSAUtil { /** * 安全服务提供者 */ private static final Provider PROVIDER = new BouncyCastleProvider(); /** * 密钥大小 */ private static final int KEY_SIZE = 1024; /** * 加密解密模式 - 填充 */ public static final String RSA_ECB_PKCS1PADDING = "RSA/ECB/PKCS1Padding"; /** * 加密解密模式 */ public static final String RSA = "RSA"; /** * 不可实例化 */ private RSAUtil() { } /** * 生成密钥对 * * @return 密钥对 */ public static KeyPair generateKeyPair() { try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( "RSA", PROVIDER); keyPairGenerator.initialize(KEY_SIZE, new SecureRandom()); return keyPairGenerator.generateKeyPair(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } /** * 通过公钥和数组加密 * * @param publicKey * 公钥 * @param data * 数据 * @return 加密后的数据 */ @SuppressWarnings("deprecation") public static byte[] encrypt(PublicKey publicKey, byte[] data) { Assert.notNull(publicKey); Assert.notNull(data); try { Cipher cipher = Cipher.getInstance("RSA", PROVIDER); cipher.init(Cipher.ENCRYPT_MODE, publicKey); int blockSize = cipher.getBlockSize();// 获得加密块大小,如:加密前数据为128个byte,而key_size=1024 // 加密块大小为127byte,加密后为128个byte;因此共有2个加密块,第一个127byte第二个为1个byte int outputSize = cipher.getOutputSize(data.length);// 获得加密块加密后块大小 int leavedSize = data.length % blockSize; int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize; byte[] raw = new byte[outputSize * blocksSize]; int i = 0; while (data.length - i * blockSize > 0) { if (data.length - i * blockSize > blockSize) { cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize); } else { cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize); } i++; } return raw; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 通过公钥和字符串加密 * * @param publicKey * 公钥 * @param text * 字符串 * @return Base64编码字符串 */ @SuppressWarnings("deprecation") public static String encrypt(PublicKey publicKey, String text) { Assert.notNull(publicKey); Assert.notNull(text); byte[] data = encrypt(publicKey, text.getBytes()); return data != null ? Base64.encodeBase64String(data) : null; } /** * 通过公钥的模量和指数构建公钥后加密字符串 * * @param modulus * @param exponent * @param text * @return */ public static String encrypt(String modulus, String exponent, String text) { try { byte[] aryExponent = Base64.decodeBase64(exponent); byte[] aryModulus = Base64.decodeBase64(modulus); BigInteger bigExponent = new BigInteger(1, aryExponent); BigInteger bigModulus = new BigInteger(1, aryModulus); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigModulus, bigExponent); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(keySpec); return encrypt(publicKey, text); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } return null; } /** * 通过私钥和数组解密 * * @param privateKey * 私钥 * @param data * 数据 * @return 解密后的数据 */ @SuppressWarnings({ "deprecation", "static-access" }) public static byte[] decrypt(PrivateKey privateKey, byte[] data) { Assert.notNull(privateKey); Assert.notNull(data); try { Cipher cipher = Cipher.getInstance("RSA", PROVIDER); cipher.init(cipher.DECRYPT_MODE, privateKey); int blockSize = cipher.getBlockSize(); ByteArrayOutputStream bout = new ByteArrayOutputStream(64); int j = 0; while (data.length - j * blockSize > 0) { bout.write(cipher.doFinal(data, j * blockSize, blockSize)); j++; } return bout.toByteArray(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 通过私钥和数组解密 - 有模式 * * @param mode * 模式 * @param privateKey * 私钥 * @param data * 数据 * @return 解密后的数据 */ @SuppressWarnings({ "deprecation", "static-access" }) public static byte[] decrypt(String mode, PrivateKey privateKey, byte[] data) { Assert.notNull(privateKey); Assert.notNull(data); try { Cipher cipher = Cipher.getInstance(mode, PROVIDER); cipher.init(cipher.DECRYPT_MODE, privateKey); int blockSize = cipher.getBlockSize(); ByteArrayOutputStream bout = new ByteArrayOutputStream(64); int j = 0; while (data.length - j * blockSize > 0) { bout.write(cipher.doFinal(data, j * blockSize, blockSize)); j++; } return bout.toByteArray(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 通过私钥和数组解密 - 点位图用 * * @param privateKey * 私钥 * @param data * 数据 * @return 解密后的数据 */ @SuppressWarnings({ "deprecation", "static-access" }) public static byte[] decryptForBitmap(PrivateKey privateKey, byte[] data) { Assert.notNull(privateKey); Assert.notNull(data); try { // 点位图ios端使用了默认的填充模式: RSA/ECB/PKCS1Padding Cipher cipher = Cipher .getInstance("RSA/ECB/PKCS1Padding", PROVIDER); cipher.init(cipher.DECRYPT_MODE, privateKey); int blockSize = cipher.getBlockSize(); ByteArrayOutputStream bout = new ByteArrayOutputStream(64); int j = 0; while (data.length - j * blockSize > 0) { bout.write(cipher.doFinal(data, j * blockSize, blockSize)); j++; } return bout.toByteArray(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 通过私钥和字符串解密 * * @param privateKey * 私钥 * @param text * Base64编码字符串 * @return 解密后的数据 */ @SuppressWarnings("deprecation") public static String decrypt(PrivateKey privateKey, String text) { Assert.notNull(privateKey); Assert.notNull(text); byte[] data = decrypt(privateKey, Base64.decodeBase64(text)); return data != null ? new String(data) : null; } /** * 通过私钥和字符串解密 - 有模式 * * @param mode * 模式 * @param privateKey * 私钥 * @param text * Base64编码字符串 * @return 解密后的数据 */ @SuppressWarnings("deprecation") public static String decrypt(String mode, PrivateKey privateKey, String text) { Assert.notNull(privateKey); Assert.notNull(text); byte[] data = decrypt(mode, privateKey, Base64.decodeBase64(text)); return data != null ? new String(data) : null; } /** * 通过私钥和字符串解密 - 点位图 * * @param privateKey * 私钥 * @param text * Base64编码字符串 * @return 解密后的数据 */ @SuppressWarnings("deprecation") public static String decryptForBitmap(PrivateKey privateKey, String text) { Assert.notNull(privateKey); Assert.notNull(text); byte[] data = decryptForBitmap(privateKey, Base64.decodeBase64(text)); return data != null ? new String(data) : null; } /** * 通过私钥的模量和指数构建私钥后和字符串解密 * * @param modulus * @param exponent * @param text * @return */ public static String decrypt(String modulus, String exponent, String text) { try { byte[] aryExponent = Base64.decodeBase64(exponent); byte[] aryModulus = Base64.decodeBase64(modulus); BigInteger bigExponent = new BigInteger(1, aryExponent); BigInteger bigModulus = new BigInteger(1, aryModulus); RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(bigModulus, bigExponent); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return decrypt(privateKey, text); } catch (Exception e) { e.printStackTrace(); } return null; } public static void main(String[] args) { String exponent = "AQAB"; String modulus = "AKJ7e1Lhn5kBnQQ++UWl8MJn9dGwCoTdXExlOsI6YVZkq4+R+Qb3gNo5v1TgHgfS2EMQ0YChr2//nJdmKc1w8bAz6XPRD4L2ZXnKDTfTOmKcel1jC7CzNUY5M1ahhEQeI6f367loH2me9UwScBN8rtIeGEGhP8E8DVriTk9g1xFv"; String password = "admin123"; System.out.print(encrypt(modulus, exponent, password)); } }