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的整数倍

posted @ 2015-11-24 00:22  kingsleylam  阅读(36022)  评论(2编辑  收藏  举报