Java加解密-RSA非对称加密算法
非对称加密算法——RSA
RSA是唯一被广泛接受并实现的通用算法。
RSA有两种模式公钥加密私钥解密和私钥加密公钥解密两种模式,其序列图如下:
在RSA算法中公钥的长度远远小于私钥的长度。以下是其java实现:
============================================================================RSA加解密工具类:
import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; 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 javax.crypto.Cipher; public class SecurityRSA { //公钥 private static final String PUBLIC_KEY = "RSAPublicKey"; //私钥 private static final String PRIVATE_KEY = "RSAPrivateKey"; /** 初始化密钥对 * @return Map 密钥对Map * @throws Exception */ public static MapinitKey() { try { //实例化密钥对生成器 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); // 初始化密钥对生成器,密钥大小为96-1024位 keyPairGenerator.initialize(1024, new SecureRandom()); //生成密钥对 KeyPair keyPair = keyPairGenerator.generateKeyPair(); //公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); //私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); //将密钥对存储在Map中 Map keyMap = new HashMap (2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } /** 加密【公钥加密,私钥解密】 * @param data 待加密数据 * @param key 公钥 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encrypt(byte[] data, byte[] key) { try { RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA") .generatePublic(new X509EncodedKeySpec(key)); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); byte[] result = cipher.doFinal(data); return result; } catch (Exception ex) { ex.printStackTrace(); } return null; } /** 解密【公钥加密,私钥解密】 * @param data 待解密数据 * @param key 私钥 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decrypt(byte[] data, byte[] key) { try { RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA") .generatePrivate(new PKCS8EncodedKeySpec(key)); //实例化 Cipher cipher = Cipher.getInstance("RSA"); //使用密钥初始化,设置为解密模式 cipher.init(Cipher.DECRYPT_MODE, priKey); //执行操作 byte[] result = cipher.doFinal(data); return result; } catch (Exception ex) { ex.printStackTrace(); } return null; } /** 取得私钥 * @param keyMap 密钥Map * @return byte[] 私钥 * @throws Exception */ public static byte[] getPrivateKey(Map keyMap) { Key key = (Key) keyMap.get(PRIVATE_KEY); return key.getEncoded(); } /** 取得公钥 * @param keyMap 密钥Map * @return byte[] 公钥 * @throws Exception */ public static byte[] getPublicKey(Map keyMap) { Key key = (Key) keyMap.get(PUBLIC_KEY); return key.getEncoded(); } }
============================================================================RSA加解密工具测试类:
@Test public void test_RSA() { //公钥 byte[] publicKey; //私钥 byte[] privateKey; //初始化密钥 //生成甲方密钥对 MapkeyMap = SecurityRSA.initKey(); publicKey = SecurityRSA.getPublicKey(keyMap); privateKey = SecurityRSA.getPrivateKey(keyMap); System.out.println("RSA公钥:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(publicKey)); System.out.println("RSA私钥:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(privateKey)); System.out.println(); System.out.println("===甲方向乙方发送加密数据==="); String msgA2B = "求知若饥,虚心若愚。"; System.out.println("原文:\n" + msgA2B); System.out.println("---甲方使用公钥对数据进行加密---"); //使用公钥对数据加密 byte[] encodeMsgA2B = SecurityRSA.encrypt(msgA2B.getBytes(), publicKey); System.out.println("RSA加密:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(encodeMsgA2B)); System.out.println("---乙方使用私钥对数据库进行解密---"); //使用私钥对数据进行解密 byte[] msgB2A = SecurityRSA.decrypt(encodeMsgA2B, privateKey); String output1 = new String(msgB2A); System.out.println("RSA解密:\n" + output1); }