java RSA 密钥生成、加密、解密
参考了一些代码,整合了下,支持分段加密,支持中文。
加密步骤大概是这样
1.base64解密公钥字符串
2.生成公钥对象
3.明文转成字节分段加密在拼接
4.密文字节base64加密,生成密文字符串
解密过程反序~
如果是android请把对应代码替换成:
Cipher cipher = Cipher.getInstance(“RSA/ECB/NoPadding”);
package security; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; 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 javax.crypto.Cipher; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public class RSACode { public static final String KEY_ALGORITHM = "RSA"; private static final String PUBLIC_KEY = "RSAPublicKey"; private static final String PRIVATE_KEY = "RSAPrivateKey"; private static final int KEY_LEN = 1024; /** <ul> <li>生成公钥和私钥 *</li> <li>@throws Exception *</li> </ul> * */ public static void getAllKeyString() throws Exception { HashMap<String, Object> keyMap = getKeys(); // 生成公钥和私钥 RSAPublicKey publicKey = (RSAPublicKey) keyMap.get(PUBLIC_KEY); RSAPrivateKey privateKey = (RSAPrivateKey) keyMap.get(PRIVATE_KEY); // 模 String modulus = publicKey.getModulus().toString(); System.out.println("模:" + modulus); // 公钥指数 String public_exponent = publicKey.getPublicExponent().toString(); System.out.println("公钥指数:" + public_exponent); System.out.println("公钥:" + encryptBASE64(publicKey.getEncoded())); // 私钥指数 String private_exponent = privateKey.getPrivateExponent().toString(); System.out.println("私钥指数:" + private_exponent); System.out.println("私钥:" + encryptBASE64(privateKey.getEncoded())); } /** <ul> <li>生成公钥和私钥 *</li> <li>@throws NoSuchAlgorithmException *</li> </ul> */ private static HashMap<String, Object> getKeys() throws NoSuchAlgorithmException { HashMap<String, Object> keyMap = new HashMap<String, Object>(); KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(KEY_LEN); KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** <ul> <li>用公钥加密 *</li> <li>@param data</li> <li>加密数据</li> <li>@param key</li> <li>通过base64加密的密钥</li> <li>@return</li> <li>@throws Exception */</li> </ul> public static String encryptByPublicKey(String data, String key) throws Exception { // 对公钥字符串解密 byte[] keyBytes = decryptBASE64(key); // 取公钥 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(x509EncodedKeySpec); // 对数据加密 String result = encryptByPublicKey(data.getBytes(), publicKey); return result; } /** <ul> <li>用私钥解密 *</li> <li>@param data</li> <li>加密数据</li> <li>@param key</li> <li>通过base64加密的密钥</li> <li>@return</li> <li>@throws Exception */</li> </ul> public static String decryptByPrivateKey(String data, String key) throws Exception { // 对私钥字符串解密 byte[] buffer = decryptBASE64(key); //获取私钥 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec); //密文base64解密 byte[] data1 = decryptBASE64(data); // 对数据解密 String result = decryptByPrivateKey(data1, privateKey); return result; } /** <ul> <li>公钥加密 *</li> <li>@param data</li> <li>@param publicKey</li> <li>@return</li> <li>@throws Exception */</li> </ul> private static String encryptByPublicKey(byte[] data, RSAPublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, publicKey); // 模长 int key_len = publicKey.getModulus().bitLength() / 8; String mi = ""; byte ming1[] = {}; // 加密数据长度 <= 模长-11 byte[][] arrays = splitArray(data, key_len - 11); for (byte[] arr : arrays) { ming1 = byteMerger(ming1,cipher.doFinal(arr)); } // } mi = encryptBASE64(ming1); return mi; } /** <ul> <li>私钥解密 *</li> <li>@param data</li> <li>@param privateKey</li> <li>@return</li> <li>@throws Exception */</li> </ul> private static String decryptByPrivateKey(byte[] data, RSAPrivateKey privateKey) throws Exception { Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, privateKey); // 模长 int key_len = privateKey.getModulus().bitLength() / 8; // 如果密文长度大于模长则要分组解密 String ming = ""; byte ming1[] = {}; byte[][] arrays = splitArray(data, key_len); for (byte[] arr : arrays) { ming1 = byteMerger(ming1,cipher.doFinal(arr)); } ming = new String(ming1); return ming; } //java 合并两个byte数组 public static byte[] byteMerger(byte[] byte_1, byte[] byte_2){ byte[] byte_3 = new byte[byte_1.length+byte_2.length]; System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length); System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length); return byte_3; } /** <ul> <li>拆分数组 */</li> </ul> public static byte[][] splitArray(byte[] data, int len) { int x = data.length / len; int y = data.length % len; int z = 0; if (y != 0) { z = 1; } byte[][] arrays = new byte[x + z][]; byte[] arr; for (int i = 0; i < x + z; i++) { arr = new byte[len]; if (i == x + z - 1 && y != 0) { System.arraycopy(data, i * len, arr, 0, y); } else { System.arraycopy(data, i * len, arr, 0, len); } arrays[i] = arr; } return arrays; } public static byte[] decryptBASE64(String key) throws Exception { return (new BASE64Decoder()).decodeBuffer(key); } public static String encryptBASE64(byte[] key) throws Exception { return (new BASE64Encoder()).encodeBuffer(key); } public static void main(String[] args) throws Exception { String publicKey = "你的公钥字符串"; String privateKey = "你的私钥字符串"; String ming ="【星爷状告华谊兄弟 追讨《西游降魔篇》8610万票房分红】为讨要《西游降魔篇》的12.48亿元票房分红,香港影星周星驰旗下公司将华谊兄弟告上法庭。但华谊兄弟在法庭上表示,该片实际票房并非公众认为的那么多,“实际票房不超过5亿元。"; // 加密后的密文 String mi = encryptByPublicKey(ming, publicKey); System.out.println(mi); // 解密后的明文 String unmi = decryptByPrivateKey(mi, privateKey); System.out.println(unmi); } }