JDK自带方法实现RSA非对称加密
1 package jdbc.pro.lin; 2 3 import java.security.InvalidKeyException; 4 import java.security.Key; 5 import java.security.KeyFactory; 6 import java.security.KeyPair; 7 import java.security.KeyPairGenerator; 8 import java.security.NoSuchAlgorithmException; 9 import java.security.PrivateKey; 10 import java.security.PublicKey; 11 import java.security.interfaces.RSAPrivateKey; 12 import java.security.interfaces.RSAPublicKey; 13 import java.security.spec.InvalidKeySpecException; 14 import java.security.spec.PKCS8EncodedKeySpec; 15 import java.security.spec.X509EncodedKeySpec; 16 import java.util.HashMap; 17 import java.util.Map; 18 19 import javax.crypto.BadPaddingException; 20 import javax.crypto.Cipher; 21 import javax.crypto.IllegalBlockSizeException; 22 import javax.crypto.NoSuchPaddingException; 23 24 import org.apache.commons.codec.binary.Base64; 25 26 public class MyRSA { 27 public static final String KEY_ALGORITHM = "RSA"; 28 /** 貌似默认是RSA/NONE/PKCS1Padding,未验证 */ 29 public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding"; 30 public static final String PUBLIC_KEY = "publicKey"; 31 public static final String PRIVATE_KEY = "privateKey"; 32 33 /** RSA密钥长度必须是64的倍数,在512~65536之间。默认是1024 */ 34 public static final int KEY_SIZE = 2048; 35 36 public static final String PLAIN_TEXT = "MANUTD is the greatest club in the world"; 37 38 public static void main(String[] args) { 39 Map<String, byte[]> keyMap = generateKeyBytes(); 40 41 // 加密 42 PublicKey publicKey = restorePublicKey(keyMap.get(PUBLIC_KEY)); 43 44 byte[] encodedText = RSAEncode(publicKey, PLAIN_TEXT.getBytes()); 45 System.out.println("RSA encoded: " + Base64.encodeBase64String(encodedText)); 46 47 // 解密 48 PrivateKey privateKey = restorePrivateKey(keyMap.get(PRIVATE_KEY)); 49 System.out.println("RSA decoded: " 50 + RSADecode(privateKey, encodedText)); 51 } 52 53 /** 54 * 生成密钥对。注意这里是生成密钥对KeyPair,再由密钥对获取公私钥 55 * 56 * @return 57 */ 58 public static Map<String, byte[]> generateKeyBytes() { 59 60 try { 61 KeyPairGenerator keyPairGenerator = KeyPairGenerator 62 .getInstance(KEY_ALGORITHM); 63 keyPairGenerator.initialize(KEY_SIZE); 64 KeyPair keyPair = keyPairGenerator.generateKeyPair(); 65 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); 66 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); 67 68 Map<String, byte[]> keyMap = new HashMap<String, byte[]>(); 69 keyMap.put(PUBLIC_KEY, publicKey.getEncoded()); 70 keyMap.put(PRIVATE_KEY, privateKey.getEncoded()); 71 return keyMap; 72 } catch (NoSuchAlgorithmException e) { 73 // TODO Auto-generated catch block 74 e.printStackTrace(); 75 } 76 return null; 77 } 78 79 /** 80 * 还原公钥,X509EncodedKeySpec 用于构建公钥的规范 81 * 82 * @param keyBytes 83 * @return 84 */ 85 public static PublicKey restorePublicKey(byte[] keyBytes) { 86 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); 87 88 try { 89 KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM); 90 PublicKey publicKey = factory.generatePublic(x509EncodedKeySpec); 91 return publicKey; 92 } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { 93 // TODO Auto-generated catch block 94 e.printStackTrace(); 95 } 96 return null; 97 } 98 99 /** 100 * 还原私钥,PKCS8EncodedKeySpec 用于构建私钥的规范 101 * 102 * @param keyBytes 103 * @return 104 */ 105 public static PrivateKey restorePrivateKey(byte[] keyBytes) { 106 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec( 107 keyBytes); 108 try { 109 KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM); 110 PrivateKey privateKey = factory 111 .generatePrivate(pkcs8EncodedKeySpec); 112 return privateKey; 113 } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { 114 // TODO Auto-generated catch block 115 e.printStackTrace(); 116 } 117 return null; 118 } 119 120 /** 121 * 加密,三步走。 122 * 123 * @param key 124 * @param plainText 125 * @return 126 */ 127 public static byte[] RSAEncode(PublicKey key, byte[] plainText) { 128 129 try { 130 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); 131 cipher.init(Cipher.ENCRYPT_MODE, key); 132 return cipher.doFinal(plainText); 133 } catch (NoSuchAlgorithmException | NoSuchPaddingException 134 | InvalidKeyException | IllegalBlockSizeException 135 | BadPaddingException e) { 136 // TODO Auto-generated catch block 137 e.printStackTrace(); 138 } 139 return null; 140 141 } 142 143 /** 144 * 解密,三步走。 145 * 146 * @param key 147 * @param encodedText 148 * @return 149 */ 150 public static String RSADecode(PrivateKey key, byte[] encodedText) { 151 152 try { 153 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); 154 cipher.init(Cipher.DECRYPT_MODE, key); 155 return new String(cipher.doFinal(encodedText)); 156 } catch (NoSuchAlgorithmException | NoSuchPaddingException 157 | InvalidKeyException | IllegalBlockSizeException 158 | BadPaddingException e) { 159 // TODO Auto-generated catch block 160 e.printStackTrace(); 161 } 162 return null; 163 164 } 165 }
几点注意:
1.用到了KeyFactory。
2.用到了公私钥的规范。
3.RSA密钥长度从512~65536,必须是64的整数倍