2/11/2013

JAVA RSA encryption and decryption


1. To generate public key and private key pair:

keytool -genkey -alias Bigkey -keyalg RSA -keysize 2048 -sigalg SHA1withRSA -keypass skpass -storepass sspass -keystore BigKeystore.jks -dname "cn=biguser"
keytool -export -rfc -keystore BigkeyStore.jks -storepass sspass -alias BigKey -file BigKey.cer

The entry in the key store has public key, private key. The certificate issued only include public key.


You can change alias, size key store name, pass word etc.. the –dname you can added more information like organization(like
   Subject: C=US, ST=Maryland, L=Pasadena, O=Brent Baccala,
                OU=FreeSoft, CN=www.freesoft.org/emailAddress=baccala@freesoft.org
.
If you don’t give it –dname it wil ask. Normally I do C, ST, L, OU, CN.

The certificate is a self signed cert.

You can also generate certificate request to CA with

Keytool –certreq ….

Once you get the CA signed certificate you can import it into the key store or use the certificate directly. Normally I like to use key store because Java crypto library uses keystore.

2. Read public key and private key from file:

Read private key:


01      public byte[] getPrivateKey(){
02         
03         KeyStore ks = null;
04         try {
05             ks = KeyStore.getInstance("jks");
06         } catch (KeyStoreException e{
07             LOGGER.error("Cannot get KeyStore instance. Failed to initialize key store for Moxy.", e);
08             return null;
09         }
10         try {
11             ks.load(new FileInputStream(keyStorePath), keyStorePassword.toCharArray());
12         } catch (Exception e){
13             LOGGER.error("Failed to initialize key store.", e);
14             return null;
15         }
16         PrivateKey privateKey = null;
17         try{
18             KeyPair keyPair=getPrivateKey(ks,keyAlias,keyPassword.toCharArray());
19             privateKey=keyPair.getPrivate();
20         }catch (Exception e){
21             LOGGER.error("Failed to get private key.", e);
22             return null;
23         }
24         byte[] privateKeyBytes = null;  
25         try{
26             privateKeyBytes = Base64.encodeBase64(privateKey.getEncoded());
27         }catch(Exception e){
28             LOGGER.error("Failed to get private key.", e);
29             return null;
30         }
31         return privateKeyBytes;
32     }
33     
34     
35     public KeyPair getPrivateKey(KeyStore keystore, String alias,char[] password{
36         
37         try {
38             Key key = keystore.getKey(alias, password);
39             if (key instanceof PrivateKey{
40                 Certificate cert = keystore.getCertificate(alias);
41                 PublicKey publicKey = cert.getPublicKey();
42                 return new KeyPair(publicKey, (PrivateKeykey);
43             }
44         } catch (Exception e{
45             e.printStackTrace();
46             return null;
47         } 
48         return null;
49     }

Read public key:


01 public byte[] getPublicKey(){
02         
03         KeyStore ks = null;
04         try {
05             ks = KeyStore.getInstance("jks");
06         } catch (KeyStoreException e{
07             LOGGER.error("Cannot get KeyStore instance. Failed to initialize key store.", e);
08             return null;
09         }
10         try {
11             ks.load(new FileInputStream(keyStorePath), keyStorePassword.toCharArray());
12         } catch (Exception e){
13             LOGGER.error("Failed to initialize key store for Moxy.", e);
14             return null;
15         }
16         PublicKey publicKey = null;
17         try{
18             KeyPair keyPair = getPublicKey(ks,keyAlias,keyPassword.toCharArray());
19             publicKey = keyPair.getPublic();
20         }catch (Exception e){
21             LOGGER.error("Failed to get public key.", e);
22             return null;
23         }
24         byte[] publicKeyBytes = null;  
25         try{
26             publicKeyBytes = Base64.encodeBase64(publicKey.getEncoded());
27         }catch(Exception e){
28             LOGGER.error("Failed to get public key.", e);
29             return null;
30         }
31         return publicKeyBytes;
32     }
33     
34     public KeyPair getPublicKey(KeyStore keystore, String alias,char[] password{
35         
36         try {
37             Key key = keystore.getKey(alias, password);
38             if (key instanceof PrivateKey{
39                 Certificate cert = keystore.getCertificate(alias);
40                 PublicKey publicKey = cert.getPublicKey();
41                 return new KeyPair(publicKey, (PrivateKeykey);
42             }
43         } catch (Exception e{
44             e.printStackTrace();
45             return null;
46         } 
47         return null;
48     }

3. Use public key and private key to encrypt and decrypt:

One way:

package security;

import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
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;

/**
 * <p>
 * RSA公钥/私钥/签名工具包
 * </p>
 * <p>
 * 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman)
 * </p>
 * <p>
 * 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/>
 * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
 * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
 * </p>
 *
 * 
@author IceWee
 * @date 2012-4-26
 * 
@version 1.0
 
*/

public class RSAUtils {

    /**
     * 加密算法RSA
     
*/

    public static final String KEY_ALGORITHM = "RSA";

    /**
     * 签名算法
     
*/

    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

    /**
     * 获取公钥的key
     
*/

    private static final String PUBLIC_KEY = "RSAPublicKey";

    /**
     * 获取私钥的key
     
*/

    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * RSA最大加密明文大小
     
*/

    private static final int MAX_ENCRYPT_BLOCK = 117;

    /**
     * RSA最大解密密文大小
     
*/

    private static final int MAX_DECRYPT_BLOCK = 128;

    /**
     * <p>
     * 生成密钥对(公钥和私钥)
     * </p>
     *
     * 
@return
     * 
@throws Exception
     
*/

    public static Map<String, Object> genKeyPair() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGen.initialize(1024);
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        Map<String, Object> keyMap = new HashMap<String, Object>(2);
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }


    /**
     * <p>
     * 用私钥对信息生成数字签名
     * </p>
     *
     * 
@param data 已加密数据
     * 
@param privateKey 私钥(BASE64编码)
     *
     * 
@return
     * 
@throws Exception
     
*/

    public static String sign(byte[] data, String privateKey) throws Exception {
        byte[] keyBytes = Base64Utils.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(privateK);
        signature.update(data);
        return Base64Utils.encode(signature.sign());
    }


    /**
     * <p>
     * 校验数字签名
     * </p>
     *
     * 
@param data 已加密数据
     * 
@param publicKey 公钥(BASE64编码)
     * 
@param sign 数字签名
     *
     * 
@return
     * 
@throws Exception
     *
     
*/

    public static boolean verify(byte[] data, String publicKey, String sign)
            throws Exception {
        byte[] keyBytes = Base64Utils.decode(publicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicK = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(publicK);
        signature.update(data);
        return signature.verify(Base64Utils.decode(sign));
    }


    /**
     * <P>
     * 私钥解密
     * </p>
     *
     * 
@param encryptedData 已加密数据
     * 
@param privateKey 私钥(BASE64编码)
     * 
@return
     * 
@throws Exception
     
*/

    public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
            throws Exception {
        byte[] keyBytes = Base64Utils.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateK);
        int inputLen = encryptedData.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            }
 else {
                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
            }

            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }

        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }


    /**
     * <p>
     * 公钥解密
     * </p>
     *
     * 
@param encryptedData 已加密数据
     * 
@param publicKey 公钥(BASE64编码)
     * 
@return
     * 
@throws Exception
     
*/

    public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)
            throws Exception {
        byte[] keyBytes = Base64Utils.decode(publicKey);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicK);
        int inputLen = encryptedData.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
            }
 else {
                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
            }

            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_DECRYPT_BLOCK;
        }

        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }


    /**
     * <p>
     * 公钥加密
     * </p>
     *
     * 
@param data 源数据
     * 
@param publicKey 公钥(BASE64编码)
     * 
@return
     * 
@throws Exception
     
*/

    public static byte[] encryptByPublicKey(byte[] data, String publicKey)
            throws Exception {
        byte[] keyBytes = Base64Utils.decode(publicKey);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key publicK = keyFactory.generatePublic(x509KeySpec);
        // 对数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            }
 else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }

            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }

        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }


    /**
     * <p>
     * 私钥加密
     * </p>
     *
     * 
@param data 源数据
     * 
@param privateKey 私钥(BASE64编码)
     * 
@return
     * 
@throws Exception
     
*/

    public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
            throws Exception {
        byte[] keyBytes = Base64Utils.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            }
 else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }

            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }

        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }


    /**
     * <p>
     * 获取私钥
     * </p>
     *
     * 
@param keyMap 密钥对
     * 
@return
     * 
@throws Exception
     
*/

    public static String getPrivateKey(Map<String, Object> keyMap)
            throws Exception {
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        return Base64Utils.encode(key.getEncoded());
    }


    /**
     * <p>
     * 获取公钥
     * </p>
     *
     * 
@param keyMap 密钥对
     * 
@return
     * 
@throws Exception
     
*/

    public static String getPublicKey(Map<String, Object> keyMap)
            throws Exception {
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        return Base64Utils.encode(key.getEncoded());
    }


}

Second way:

  1. package com.rsa;  
  2. import java.security.Key;  
  3. import java.security.KeyFactory;  
  4. import java.security.KeyPair;  
  5. import java.security.KeyPairGenerator;  
  6. import java.security.PrivateKey;  
  7. import java.security.PublicKey;  
  8. import java.security.Signature;  
  9. import java.security.interfaces.RSAPrivateKey;  
  10. import java.security.interfaces.RSAPublicKey;  
  11. import java.security.spec.PKCS8EncodedKeySpec;  
  12. import java.security.spec.X509EncodedKeySpec;  
  13. import java.util.HashMap;  
  14. import java.util.Map;  
  15.   
  16. import javax.crypto.Cipher;  
  17.   
  18. /** *//**  
  19. * RSA安全编码组件  
  20. *    
  21. * @version 1.0  
  22. * @since 1.0  
  23. */   
  24. public class RSACoder  extends Coder{     
  25.     public static final String KEY_ALGORITHM = "RSA";     
  26.     public static final String SIGNATURE_ALGORITHM = "MD5withRSA";     
  27.   
  28.     private static final String PUBLIC_KEY = "RSAPublicKey";     
  29.     private static final String PRIVATE_KEY = "RSAPrivateKey";     
  30.   
  31.     /** *//**  
  32.      * 用私钥对信息生成数字签名  
  33.      *    
  34.      * @param data  
  35.      *            加密数据  
  36.      * @param privateKey  
  37.      *            私钥  
  38.      *    
  39.      * @return  
  40.      * @throws Exception  
  41.      */   
  42.     public static String sign(byte[] data, String privateKey) throws Exception {     
  43.         // 解密由base64编码的私钥     
  44.         byte[] keyBytes = decryptBASE64(privateKey);     
  45.   
  46.         // 构造PKCS8EncodedKeySpec对象     
  47.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);     
  48.   
  49.         // KEY_ALGORITHM 指定的加密算法     
  50.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);     
  51.   
  52.         // 取私钥匙对象     
  53.         PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);     
  54.   
  55.         // 用私钥对信息生成数字签名     
  56.         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);     
  57.         signature.initSign(priKey);     
  58.         signature.update(data);     
  59.   
  60.         return encryptBASE64(signature.sign());     
  61.     }     
  62.   
  63.     /** *//**  
  64.      * 校验数字签名  
  65.      *    
  66.      * @param data  
  67.      *            加密数据  
  68.      * @param publicKey  
  69.      *            公钥  
  70.      * @param sign  
  71.      *            数字签名  
  72.      *    
  73.      * @return 校验成功返回true 失败返回false  
  74.      * @throws Exception  
  75.      *    
  76.      */   
  77.     public static boolean verify(byte[] data, String publicKey, String sign)     
  78.             throws Exception {     
  79.   
  80.         // 解密由base64编码的公钥     
  81.         byte[] keyBytes = decryptBASE64(publicKey);     
  82.   
  83.         // 构造X509EncodedKeySpec对象     
  84.         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);     
  85.   
  86.         // KEY_ALGORITHM 指定的加密算法     
  87.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);     
  88.   
  89.         // 取公钥匙对象     
  90.         PublicKey pubKey = keyFactory.generatePublic(keySpec);     
  91.   
  92.         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);     
  93.         signature.initVerify(pubKey);     
  94.         signature.update(data);     
  95.   
  96.         // 验证签名是否正常     
  97.         return signature.verify(decryptBASE64(sign));     
  98.     }     
  99.   
  100.     /** *//**  
  101.      * 解密<br>  
  102. * 用私钥解密 http://www.5a520.cn http://www.feng123.com 
  103.      *    
  104.      * @param data  
  105.      * @param key  
  106.      * @return  
  107.      * @throws Exception  
  108.      */   
  109.     public static byte[] decryptByPrivateKey(byte[] data, String key)     
  110.             throws Exception {     
  111.         // 对密钥解密     
  112.         byte[] keyBytes = decryptBASE64(key);     
  113.   
  114.         // 取得私钥     
  115.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);     
  116.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);     
  117.         Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);     
  118.   
  119.         // 对数据解密     
  120.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());     
  121.         cipher.init(Cipher.DECRYPT_MODE, privateKey);     
  122.   
  123.         return cipher.doFinal(data);     
  124.     }     
  125.   
  126.     /** *//**  
  127.      * 解密<br>  
  128.      * 用私钥解密  
  129.      *    
  130.      * @param data  
  131.      * @param key  
  132.      * @return  
  133.      * @throws Exception  
  134.      */   
  135.     public static byte[] decryptByPublicKey(byte[] data, String key)     
  136.             throws Exception {     
  137.         // 对密钥解密     
  138.         byte[] keyBytes = decryptBASE64(key);     
  139.   
  140.         // 取得公钥     
  141.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);     
  142.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);     
  143.         Key publicKey = keyFactory.generatePublic(x509KeySpec);     
  144.   
  145.         // 对数据解密     
  146.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());     
  147.         cipher.init(Cipher.DECRYPT_MODE, publicKey);     
  148.   
  149.         return cipher.doFinal(data);     
  150.     }     
  151.   
  152.     /** *//**  
  153.      * 加密<br>  
  154.      * 用公钥加密  
  155.      *    
  156.      * @param data  
  157.      * @param key  
  158.      * @return  
  159.      * @throws Exception  
  160.      */   
  161.     public static byte[] encryptByPublicKey(byte[] data, String key)     
  162.             throws Exception {     
  163.         // 对公钥解密     
  164.         byte[] keyBytes = decryptBASE64(key);     
  165.   
  166.         // 取得公钥     
  167.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);     
  168.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);     
  169.         Key publicKey = keyFactory.generatePublic(x509KeySpec);     
  170.   
  171.         // 对数据加密     
  172.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());     
  173.         cipher.init(Cipher.ENCRYPT_MODE, publicKey);     
  174.   
  175.         return cipher.doFinal(data);     
  176.     }     
  177.   
  178.     /** *//**  
  179.      * 加密<br>  
  180.      * 用私钥加密  
  181.      *    
  182.      * @param data  
  183.      * @param key  
  184.      * @return  
  185.      * @throws Exception  
  186.      */   
  187.     public static byte[] encryptByPrivateKey(byte[] data, String key)     
  188.             throws Exception {     
  189.         // 对密钥解密     
  190.         byte[] keyBytes = decryptBASE64(key);     
  191.   
  192.         // 取得私钥     
  193.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);     
  194.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);     
  195.         Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);     
  196.   
  197.         // 对数据加密     
  198.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());     
  199.         cipher.init(Cipher.ENCRYPT_MODE, privateKey);     
  200.   
  201.         return cipher.doFinal(data);     
  202.     }     
  203.   
  204.     /** *//**  
  205.      * 取得私钥  
  206.      *    
  207.      * @param keyMap  
  208.      * @return  
  209.      * @throws Exception  
  210.      */   
  211.     public static String getPrivateKey(Map<String, Object> keyMap)     
  212.             throws Exception {     
  213.         Key key = (Key) keyMap.get(PRIVATE_KEY);     
  214.   
  215.         return encryptBASE64(key.getEncoded());     
  216.     }     
  217.   
  218.     /** *//**  
  219.      * 取得公钥  
  220.      *    
  221.      * @param keyMap  
  222.      * @return  
  223.      * @throws Exception  
  224.      */   
  225.     public static String getPublicKey(Map<String, Object> keyMap)     
  226.             throws Exception {     
  227.         Key key = (Key) keyMap.get(PUBLIC_KEY);     
  228.   
  229.         return encryptBASE64(key.getEncoded());     
  230.     }     
  231.   
  232.     /** *//**  
  233.      * 初始化密钥  
  234.      *    
  235.      * @return  
  236.      * @throws Exception  
  237.      */   
  238.     public static Map<String, Object> initKey() throws Exception {     
  239.         KeyPairGenerator keyPairGen = KeyPairGenerator     
  240.                 .getInstance(KEY_ALGORITHM);     
  241.         keyPairGen.initialize(1024);     
  242.   
  243.         KeyPair keyPair = keyPairGen.generateKeyPair();     
  244.   
  245.         // 公钥     
  246.         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();     
  247.   
  248.         // 私钥     
  249.         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();     
  250.   
  251.         Map<String, Object> keyMap = new HashMap<String, Object>(2);     
  252.   
  253.         keyMap.put(PUBLIC_KEY, publicKey);     
  254.         keyMap.put(PRIVATE_KEY, privateKey);     
  255.         return keyMap;     
  256.     }     
  257. }   

2.3 Junit进行测试。

[java] view plaincopy
  1. package com.rsa;  
  2. import static org.junit.Assert.*;     
  3.   
  4. import org.junit.Before;     
  5. import org.junit.Test;     
  6.   
  7. import java.util.Map;     
  8.   
  9. /** *//**  
  10. *    
  11. *   使用Junit4 来进行单元测试。 
  12. * @version 1.0  
  13. * @since 1.0  
  14. */   
  15. public class RSACoderTest {     
  16.     private String publicKey;     
  17.     private String privateKey;     
  18.   
  19.     @Before   
  20.     public void setUp() throws Exception {     
  21.         Map<String, Object> keyMap = RSACoder.initKey();     
  22.   
  23.         publicKey = RSACoder.getPublicKey(keyMap);     
  24.         privateKey = RSACoder.getPrivateKey(keyMap);     
  25.         System.err.println("公钥: \n\r" + publicKey);     
  26.         System.err.println("私钥: \n\r" + privateKey);     
  27.     }     
  28.   
  29.     @Test   
  30.     public void testPub2Pri() throws Exception {     
  31.         System.err.println("公钥加密——私钥解密");     
  32.         String inputStr = "abc";     
  33.         byte[] data = inputStr.getBytes();     
  34.   
  35.         byte[] encodedData = RSACoder.encryptByPublicKey(data, publicKey);     
  36.   
  37.         byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,     
  38.                 privateKey);     
  39.   
  40.         String outputStr = new String(decodedData);     
  41.         System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);     
  42.         assertEquals(inputStr, outputStr);     
  43.   
  44.     }     
  45.   
  46.     @Test   
  47.     public void testPri2Pub() throws Exception {     
  48.         System.err.println("私钥加密——公钥解密");     
  49.         String inputStr = "sign";     
  50.         byte[] data = inputStr.getBytes();     
  51.   
  52.         byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);     
  53.   
  54.         byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);     
  55.   
  56.         String outputStr = new String(decodedData);     
  57.         System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);     
  58.         assertEquals(inputStr, outputStr);    //使用Junit断言,加密前的原文与解密后的明文是否一致。   
  59.   
  60.         System.err.println("私钥签名——公钥验证签名");     
  61.         // 产生签名   这里的encodedData可以与下面的encodedData同时换成new int[]{2,45}  
  62.         String sign = RSACoder.sign(encodedData, privateKey); //数字签名只要公钥人拿到签名的sign对比  
  63.         //,自己公钥通过同样的byte[]运算得到签名是否一致。是到致代表这个公钥就是对的,就是为现在发私钥人服务的。  
  64.         System.err.println("签名:\r" + sign);     
  65.   
  66.         // 验证签名     
  67.         boolean status = RSACoder.verify(encodedData, publicKey, sign);     
  68.         System.err.println("状态:\r" + status);     
  69.         assertTrue(status);     
  70.   
  71.     }     
  72.   
  73. }   

Personal Code:

 public static final String KEY_DECRYPT_ALGORITHM = "RSA";
public byte[] decryptByPrivateKey(String encryptedData){
     
       byte[] encryptedDataBytes = null;
       byte[] decryptedData = null;
      
       PKCS8EncodedKeySpec pkcs8KeySpec = null;
       try {
            encryptedDataBytes = Base64.decodeBase64(encryptedData.getBytes());
            //byte[] decodedPrivateKey = Base64.decodeBase64(privateKey);
            pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_DECRYPT_ALGORITHM);
            Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, privateK);
            decryptedData = cipher.doFinal(encryptedDataBytes);
            
       }catch (NoSuchAlgorithmException e1{
           LOGGER.error("Key Decrypt Algorithm not found. Root Exception=>", e1);
           return null;
       }catch (InvalidKeySpecException e2{
           LOGGER.error("Invalid key spec. Root Exception=>", e2);
           return null;
       }catch (NoSuchPaddingException e3{
           LOGGER.error("Wrong decryption padding. Root Exception=>", e3);
           return null;
       }catch (InvalidKeyException e4{
           LOGGER.error("Invalid key. Root Exception=>", e4);
           return null;
       } catch (IllegalBlockSizeException e5{
           LOGGER.error("Illegal Block Size. Root Exception=>", e5);
           return null;
       } catch (BadPaddingException e6{
           LOGGER.error("Bad padding. Root Exception=>", e6);
           return null;
       }catch(Exception e){
           LOGGER.error("Error Happened when decrypted the decryption key. Root Exception=>", e);
           return null;
       } 
       return decryptedData;

   }
 
   public byte[] decryptKeyVer2(String encryptedKey){
     
       if(StringUtils.isEmpty(encryptedKey)){
           LOGGER.error("The encrypted AES key is null.");
           return null;
       }
       byte[] encryptedKeyBytes = null;
       Cipher cipher = null;
       ByteArrayOutputStream out = null;
       byte[] decryptedData = null;
       try{
            encryptedKeyBytes = Base64.decodeBase64(encryptedKey.getBytes());
            byte[] decodedPrivateKey = Base64.decodeBase64(privateKey);
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(decodedPrivateKey);
            KeyFactory keyFactory = KeyFactory.getInstance(PUBLIC_KEY_ALGORITHM);
            Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
            cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, privateK);
            int inputLen = encryptedKeyBytes.length;
            out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                    cache = cipher.doFinal(encryptedKeyBytes, offSet, MAX_DECRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(encryptedKeyBytes, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_DECRYPT_BLOCK;
            }
            decryptedData = out.toByteArray();
            out.close();
       }catch(Exception e){
           LOGGER.error("Error Happened when decrypt. Root Exception=>", e);
           return null;
       }finally{
           try{
               out.close();
           }catch(Exception e){
               LOGGER.error("Cannot close the output stream when decrypting the AES key", e);
           }
       }
       return decryptedData;
   }

public byte[] encryptByPublicKeyVer2(byte[] data){     

   if(data==null || data.length<1){
       return null;
   }
   byte[] result = null;
   try{
       byte[] keyBytes = Base64.decodeBase64(publicKey);     
       X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);     
       KeyFactory keyFactory = KeyFactory.getInstance(PUBLIC_KEY_ALGORITHM);     
       Key publicKey = keyFactory.generatePublic(x509KeySpec);     
       Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());     
       cipher.init(Cipher.ENCRYPT_MODE, publicKey); 
       result = cipher.doFinal(data);
   }catch (Exception e{
       LOGGER.error("Cannot encrypt by RSA",e);
       return null;
   }
   return result;
} 

public byte[] encryptByPublicKey(byte[] data){
   
    ByteArrayOutputStream out = null;
    byte[] encryptedData = null;
   try{
       byte[] keyBytes = Base64.decodeBase64(publicKey);
       X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
       KeyFactory keyFactory = KeyFactory.getInstance(PUBLIC_KEY_ALGORITHM);
       Key publicK = keyFactory.generatePublic(x509KeySpec);

       Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
       cipher.init(Cipher.ENCRYPT_MODE, publicK);
       int inputLen = data.length;
       out = new ByteArrayOutputStream();
       int offSet = 0;
       byte[] cache;
       int i = 0;
       while (inputLen - offSet > 0{
           if (inputLen - offSet > MAX_ENCRYPT_BLOCK{
               cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
           } else {
               cache = cipher.doFinal(data, offSet, inputLen - offSet);
           }
           out.write(cache, 0, cache.length);
           i++;
           offSet = i * MAX_ENCRYPT_BLOCK;
       }
       encryptedData = out.toByteArray();
       out.close();
   }catch(Exception e){
       LOGGER.error(e);
   }finally{
       try{
           out.close();
       }catch(Exception e){
           LOGGER.error("Cannot close the output stream when decrypting.", e);
       }
   }
   
   return encryptedData;
}














No comments:

Post a Comment