import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; import org.springframework.util.Base64Utils; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.ShortBufferException; 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; import java.util.UUID; import java.util.regex.Pattern; /** * RSA安全编码组件 * * @author wbw * @version 1.0 */ public class RSAUtils { /** * 非对称加密密钥算法 */ public static final String KEY_ALGORITHM_RSA = "RSA"; private static String RSA_JAVA = "RSA/None/PKCS1Padding"; /** * 公钥 */ private static final String RSA_PUBLIC_KEY = "RSAPublicKey"; /** * 私钥 */ private static final String RSA_PRIVATE_KEY = "RSAPrivateKey"; /** * RSA密钥长度 * 默认1024位, * 密钥长度必须是64的倍数, * 范围在512至65536位之间。 */ private static final int KEY_SIZE = 1024; static{ Security.insertProviderAt(new BouncyCastleProvider(), 1); } /** * 私钥解密 * * @param data * 待解密数据 * @param key * 私钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception { // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA); // 生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(RSA_JAVA); cipher.init(Cipher.DECRYPT_MODE, privateKey); int blockSize = cipher.getBlockSize(); if(blockSize>0){ 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(); } return cipher.doFinal(data); } /** * 公钥解密 * * @param data * 待解密数据 * @param key * 公钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception { // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA); // 生成公钥 PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(RSA_JAVA); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 公钥加密 * * @param data * 待加密数据 * @param key * 公钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception { // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA); PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(RSA_JAVA); cipher.init(Cipher.ENCRYPT_MODE, publicKey); int blockSize = cipher.getBlockSize(); byte[] raw = getBytes(data, cipher, blockSize); if (raw != null) { return raw; } return cipher.doFinal(data); } private static byte[] getBytes(byte[] data, Cipher cipher, int blockSize) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { if(blockSize>0){ 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,remainSize=0; while ((remainSize = data.length - i * blockSize) > 0) { int inputLen = remainSize > blockSize?blockSize:remainSize; cipher.doFinal(data, i * blockSize, inputLen, raw, i * outputSize); i++; } return raw; } return null; } /** * 私钥加密 * * @param data * 待加密数据 * @param key * 私钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception { // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA); // 生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(RSA_JAVA); cipher.init(Cipher.ENCRYPT_MODE, privateKey); int blockSize = cipher.getBlockSize(); byte[] raw = getBytes(data, cipher, blockSize); return cipher.doFinal(data); } /** * 取得私钥 * * @param keyMap * 密钥Map * @return key 私钥 * @throws Exception */ public static Key getPrivateKey(Map<String, Key> keyMap) throws Exception { return keyMap.get(RSA_PRIVATE_KEY); } /** * 取得私钥 * * @param keyMap * 密钥Map * @return byte[] 私钥 * @throws Exception */ public static byte[] getPrivateKeyByte(Map<String, Key> keyMap) throws Exception { return keyMap.get(RSA_PRIVATE_KEY).getEncoded(); } /** * 取得公钥 * * @param keyMap * 密钥Map * @return key 公钥 * @throws Exception */ public static Key getPublicKey(Map<String, Key> keyMap) throws Exception { return keyMap.get(RSA_PUBLIC_KEY); } /** * 取得公钥 * * @param keyMap * 密钥Map * @return byte[] 公钥 * @throws Exception */ public static byte[] getPublicKeyByte(Map<String, Key> keyMap) throws Exception { return keyMap.get(RSA_PUBLIC_KEY).getEncoded(); } /** * 初始化密钥 * @param seed 种子 * @return Map 密钥Map * @throws Exception */ public static Map<String,Key> initKey(byte[] seed)throws Exception{ // 实例化密钥对生成器 KeyPairGenerator keyPairGen = KeyPairGenerator .getInstance(KEY_ALGORITHM_RSA); // 初始化密钥对生成器 keyPairGen.initialize(KEY_SIZE, new SecureRandom(seed) ); // 生成密钥对 KeyPair keyPair = keyPairGen.generateKeyPair(); // 公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 封装密钥 Map<String, Key> keyMap = new HashMap<String, Key>(2); keyMap.put(RSA_PUBLIC_KEY, publicKey); keyMap.put(RSA_PRIVATE_KEY, privateKey); return keyMap; } /** * 初始化密钥 * @param seed 种子 * @return Map 密钥Map * @throws Exception */ public static Map<String,Key> initKey(String seed)throws Exception{ return initKey(seed.getBytes()); } /** * 初始化密钥 * * @return Map 密钥Map * @throws Exception */ public static Map<String, Key> initKey() throws Exception { return initKey(UUID.randomUUID().toString().getBytes()); } public static PublicKey getPublicRSAKey(String key) throws Exception { X509EncodedKeySpec x509 = new X509EncodedKeySpec(Base64.decode(key)); KeyFactory kf = KeyFactory.getInstance(KEY_ALGORITHM_RSA); return kf.generatePublic(x509); } public static PrivateKey getPrivateRSAKey(String key) throws Exception { PKCS8EncodedKeySpec pkgs8 = new PKCS8EncodedKeySpec(Base64.decode(key)); KeyFactory kf = KeyFactory.getInstance(KEY_ALGORITHM_RSA); return kf.generatePrivate(pkgs8); } }
调用
class RSAUtilsTest { private static String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAHzDQssuIce0x5thZdTbS1N/iJtkpluE5X3sU0nvRIUAmkqVi9zCuJrRizpOCSGatkX21gQjwJRb7Fz/H38HuyeSv6myLHBbQU866eU3nJPpuQcYiWQMbcWv+y2Y9y0oOqjEZwv+ERj0mLYGO+SHftYwJ3T6yyeHXd3VcMBKkiQIDAQAB"; private static String PRIVATE_KEY= "MIICWwIBAAKBgQCAHzDQssuIce0x5thZdTbS1N/iJtkpluE5X3sU0nvRIUAmkqVi9zCuJrRizpOCSGatkX21gQjwJRb7Fz/H38HuyeSv6myLHBbQU866eU3nJPpuQcYiWQMbcWv+y2Y9y0oOqjEZwv+ERj0mLYGO+SHftYwJ3T6yyeHXd3VcMBKkiQIDAQABAoGAGk/Ng56kY/IZpzzkQ4Lp7mRfUh9uS7c7q7+rFDyhxvIQLZvCMU/YhHtYYk5QRto9k/mkGmlUf5TuYkSFCbQvLGGpc7WKOvEuoHzXcHAc1peQa5+7WKDjhs8R9W6T5g4cYnqknTWNh1nfVbM9GOBdDLFxBJgJVh/r2fvhpB1WL4ECQQCQf2yrKiiHJsEIuO67iVRy54HcEnZvV0nYVnhFNWfDLtMIm/6I7G6n0MZHGWCIs77EPAhiMtg9IioE3I0Q/neZAkEA4vzQE6VcG12MoYkmudgmpnO3YjPdST9Ui1sEhrxvqXNru+ykfwx3kWZt42yv5471FytVSPJwXwX63fnfNp7qcQJAbRaWLr68LBR45SHgsdpi1ACtTDzwBuzKRjY5xF4mQPenwLcsOajtfWojVuf0th+lJLcByUkDcVvKhzMOmMbT+QJAPc9GAfOHb1Q8FUi5qOW5MJ5WE4G4Algid4gjZWUuqt/pOFUqPgZxEMDpr4JLLCz7hIGiSajq/JUuSP/fzonboQJAbWcNpngj5xddtGn/PVE1Zv9iwJmfD+/9Y9nQ+0AO/FFK6ruFEjikefkrB8byBcGy6fU7ax7AjqsF5HdsE1BfaA=="; public static String rsaPublicEncryptAndPrivateKeyDecrypt(String rawText) { byte[] privateKey = Base64Utils.decodeFromString(PRIVATE_KEY); byte[] publicKey = Base64Utils.decodeFromString(PUBLIC_KEY); try { System.out.println("原数据为:"+rawText); byte[] encryptByPublicKey = RSAUtils.encryptByPublicKey(rawText.getBytes(), publicKey); String encryptByPublicKeyString = Base64Utils.encodeToString(encryptByPublicKey); System.out.println("公钥加密后的数据为:"+encryptByPublicKeyString); byte[] decryptByPrivateKey = RSAUtils.decryptByPrivateKey( Base64Utils.decodeFromString(encryptByPublicKeyString), privateKey); String result=new String(decryptByPrivateKey); System.out.println("私钥解密后的数据为:"+result); return result; } catch (Exception e) { System.out.println(e); } return null; } public static void main(String[] args) { System.out.println(rsaPublicEncryptAndPrivateKeyDecrypt("Hello world!")); } }
输出
原数据为:Hello world! 公钥加密后的数据为:fymr5G4ZWIy3ek9xJ+KAtNAKHVOjX9qPgPDF9wSofGaPsOuRMTz3LvvmpA8CCYJT/Y3TzXEQPWQjUwhcqH/AkDorf78oe1zbXE3m47Unua7yhsGNZdCE14j5JfXB5t6JZ3VOBycLMXgCw6Ol3m3lkaaa6xxAuH5sMN0haseERs8= 私钥解密后的数据为:Hello world!