openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem
 openssl rsa -in private_key.pem -pubout -out public_key.pem
 openssl pkcs8 -topk8 -inform PEM -in private_key.pem -outform PEM -nocrypt -out private_key_pkcs8.pem 
package com.test.ssl;
import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.security.InvalidKeyException;
 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.InvalidKeySpecException;
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.X509EncodedKeySpec;import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
 import javax.crypto.IllegalBlockSizeException;
 import javax.crypto.NoSuchPaddingException;import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sun.misc.BASE64Decoder;
public class RSAEncrypt {
 private static final String DEFAULT_PUBLIC_KEY= 
   "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChDzcjw/rWgFwnxunbKp7/4e8w" + "\r" +
   "/UmXx2jk6qEEn69t6N2R1i/LmcyDT1xr/T2AHGOiXNQ5V8W4iCaaeNawi7aJaRht" + "\r" +
   "Vx1uOH/2U378fscEESEG8XDqll0GCfB1/TjKI2aitVSzXOtRs8kYgGU78f7VmDNg" + "\r" +
   "XIlk3gdhnzh+uoEQywIDAQAB" + "\r";
  
  private static final String DEFAULT_PRIVATE_KEY=
   "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKEPNyPD+taAXCfG" + "\r" +
   "6dsqnv/h7zD9SZfHaOTqoQSfr23o3ZHWL8uZzINPXGv9PYAcY6Jc1DlXxbiIJpp4" + "\r" +
   "1rCLtolpGG1XHW44f/ZTfvx+xwQRIQbxcOqWXQYJ8HX9OMojZqK1VLNc61GzyRiA" + "\r" +
   "ZTvx/tWYM2BciWTeB2GfOH66gRDLAgMBAAECgYBp4qTvoJKynuT3SbDJY/XwaEtm" + "\r" +
   "u768SF9P0GlXrtwYuDWjAVue0VhBI9WxMWZTaVafkcP8hxX4QZqPh84td0zjcq3j" + "\r" +
   "DLOegAFJkIorGzq5FyK7ydBoU1TLjFV459c8dTZMTu+LgsOTD11/V/Jr4NJxIudo" + "\r" +
   "MBQ3c4cHmOoYv4uzkQJBANR+7Fc3e6oZgqTOesqPSPqljbsdF9E4x4eDFuOecCkJ" + "\r" +
   "DvVLOOoAzvtHfAiUp+H3fk4hXRpALiNBEHiIdhIuX2UCQQDCCHiPHFd4gC58yyCM" + "\r" +
   "6Leqkmoa+6YpfRb3oxykLBXcWx7DtbX+ayKy5OQmnkEG+MW8XB8wAdiUl0/tb6cQ" + "\r" +
   "FaRvAkBhvP94Hk0DMDinFVHlWYJ3xy4pongSA8vCyMj+aSGtvjzjFnZXK4gIjBjA" + "\r" +
   "2Z9ekDfIOBBawqp2DLdGuX2VXz8BAkByMuIh+KBSv76cnEDwLhfLQJlKgEnvqTvX" + "\r" +
   "TB0TUw8avlaBAXW34/5sI+NUB1hmbgyTK/T/IFcEPXpBWLGO+e3pAkAGWLpnH0Zh" + "\r" +
   "Fae7oAqkMAd3xCNY6ec180tAe57hZ6kS+SYLKwb4gGzYaCxc22vMtYksXHtUeamo" + "\r" +
   "1NMLzI2ZfUoX" + "\r";
  
  /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;
    
    /** *//**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = 128; /**
   * 私钥
   */
  private RSAPrivateKey privateKey; /**
   * 公钥
   */
  private RSAPublicKey publicKey;
  
  /**
   * 字节数据转字符串专用集合
   */
  private static final char[] HEX_CHAR= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  
  /**
   * 获取私钥
   * @return 当前的私钥对象
   */
  public RSAPrivateKey getPrivateKey() {
   return privateKey;
  } /**
   * 获取公钥
   * @return 当前的公钥对象
   */
  public RSAPublicKey getPublicKey() {
   return publicKey;
  } /**
   * 随机生成密钥对
   */
  public void genKeyPair(){
   KeyPairGenerator keyPairGen= null;
   try {
    keyPairGen= KeyPairGenerator.getInstance("RSA");
   } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
   }
   keyPairGen.initialize(1024, new SecureRandom());
   KeyPair keyPair= keyPairGen.generateKeyPair();
   this.privateKey= (RSAPrivateKey) keyPair.getPrivate();
   this.publicKey= (RSAPublicKey) keyPair.getPublic();
  }
  
  /**
   * 从文件中输入流中加载公钥
   * @param in 公钥输入流
   * @throws Exception 加载公钥时产生的异常
   */
  public void loadPublicKey(InputStream in) throws Exception{
   try {
    BufferedReader br= new BufferedReader(new InputStreamReader(in));
    String readLine= null;
    StringBuilder sb= new StringBuilder();
    while((readLine= br.readLine())!=null){
     if(readLine.charAt(0)=='-'){
      continue;
     }else{
      sb.append(readLine);
      sb.append('\r');
     }
    }
    loadPublicKey(sb.toString());
   } catch (IOException e) {
    throw new Exception("公钥数据流读取错误");
   } catch (NullPointerException e) {
    throw new Exception("公钥输入流为空");
   }
  }  /**
   * 从字符串中加载公钥
   * @param publicKeyStr 公钥数据字符串
   * @throws Exception 加载公钥时产生的异常
   */
  public void loadPublicKey(String publicKeyStr) throws Exception{
   try {
    BASE64Decoder base64Decoder= new BASE64Decoder();
    byte[] buffer= base64Decoder.decodeBuffer(publicKeyStr);
    KeyFactory keyFactory= KeyFactory.getInstance("RSA");
    X509EncodedKeySpec keySpec= new X509EncodedKeySpec(buffer);
    this.publicKey= (RSAPublicKey) keyFactory.generatePublic(keySpec);
   } catch (NoSuchAlgorithmException e) {
    throw new Exception("无此算法");
   } catch (InvalidKeySpecException e) {
    throw new Exception("公钥非法");
   } catch (IOException e) {
    throw new Exception("公钥数据内容读取错误");
   } catch (NullPointerException e) {
    throw new Exception("公钥数据为空");
   }
  } /**
   * 从文件中加载私钥
   * @param keyFileName 私钥文件名
   * @return 是否成功
   * @throws Exception 
   */
  public void loadPrivateKey(InputStream in) throws Exception{
   try {
    BufferedReader br= new BufferedReader(new InputStreamReader(in));
    String readLine= null;
    StringBuilder sb= new StringBuilder();
    while((readLine= br.readLine())!=null){
     if(readLine.charAt(0)=='-'){
      continue;
     }else{
      sb.append(readLine);
      sb.append('\r');
     }
    }
    loadPrivateKey(sb.toString());
   } catch (IOException e) {
    throw new Exception("私钥数据读取错误");
   } catch (NullPointerException e) {
    throw new Exception("私钥输入流为空");
   }
  } public void loadPrivateKey(String privateKeyStr) throws Exception{
   try {
    BASE64Decoder base64Decoder= new BASE64Decoder();
    byte[] buffer= base64Decoder.decodeBuffer(privateKeyStr);
    PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer);
    KeyFactory keyFactory= KeyFactory.getInstance("RSA");
    this.privateKey= (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
   } catch (NoSuchAlgorithmException e) {
    throw new Exception("无此算法");
   } catch (InvalidKeySpecException e) {
    throw new Exception("私钥非法");
   } catch (IOException e) {
    throw new Exception("私钥数据内容读取错误");
   } catch (NullPointerException e) {
    throw new Exception("私钥数据为空");
   }
  }
  
  /**
   * 加密过程
   * @param publicKey 公钥
   * @param plainTextData 明文数据
   * @return
   * @throws Exception 加密过程中的异常信息
   */
  public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception{
   if(publicKey== null){
    throw new Exception("加密公钥为空, 请设置");
   }
   Cipher cipher= null;
   ByteArrayOutputStream out = new ByteArrayOutputStream();
         int offSet = 0;
         byte[] cache;
         int i = 0;  try {
    cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    int inputLen = plainTextData.length;
    //分段对数据加密
    while(inputLen - offSet > 0) {
     if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
      cache = cipher.doFinal(plainTextData,offSet,MAX_ENCRYPT_BLOCK);
     } else {
      cache = cipher.doFinal(plainTextData, offSet, inputLen - offSet);
     }
     out.write(cache,0,cache.length);
     i++;
     offSet = i*MAX_ENCRYPT_BLOCK;
    }
    byte[] output= out.toByteArray();//cipher.doFinal(plainTextData);
    out.close();
    return output;
   } catch (NoSuchAlgorithmException e) {
    throw new Exception("无此加密算法");
   } catch (NoSuchPaddingException e) {
    e.printStackTrace();
    return null;
   }catch (InvalidKeyException e) {
    throw new Exception("加密公钥非法,请检查");
   } catch (IllegalBlockSizeException e) {
    throw new Exception("明文长度非法");
   } catch (BadPaddingException e) {
    throw new Exception("明文数据已损坏");
   }
  } /**
   * 解密过程
   * @param privateKey 私钥
   * @param cipherData 密文数据
   * @return 明文
   * @throws Exception 解密过程中的异常信息
   */
  public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception{
   if (privateKey== null){
    throw new Exception("解密私钥为空, 请设置");
   }
   Cipher cipher= null;
   ByteArrayOutputStream out = new ByteArrayOutputStream();
         int offSet = 0;
         byte[] cache;
         int i = 0;
   try {
    cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    int inputLen = cipherData.length;
    //分段对数据加密
    while(inputLen - offSet > 0) {
     if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
      cache = cipher.doFinal(cipherData,offSet,MAX_DECRYPT_BLOCK);
     } else {
      cache = cipher.doFinal(cipherData, offSet, inputLen - offSet);
     }
     out.write(cache,0,cache.length);
     i++;
     offSet = i*MAX_DECRYPT_BLOCK;
    }
    byte[] output= out.toByteArray();//cipher.doFinal(plainTextData);
    out.close();
    
    //byte[] output= cipher.doFinal(cipherData);
    return output;
   } catch (NoSuchAlgorithmException e) {
    throw new Exception("无此解密算法");
   } catch (NoSuchPaddingException e) {
    e.printStackTrace();
    return null;
   }catch (InvalidKeyException e) {
    throw new Exception("解密私钥非法,请检查");
   } catch (IllegalBlockSizeException e) {
    throw new Exception("密文长度非法");
   } catch (BadPaddingException e) {
    throw new Exception("密文数据已损坏");
   }  
  }
  
  /**
   * 字节数据转十六进制字符串
   * @param data 输入数据
   * @return 十六进制内容
   */
  public static String byteArrayToString(byte[] data){
   StringBuilder stringBuilder= new StringBuilder();
   for (int i=0; i<data.length; i++){
    //取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移
    stringBuilder.append(HEX_CHAR[(data[i] & 0xf0)>>> 4]);
    //取出字节的低四位 作为索引得到相应的十六进制标识符
    stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
    if (i<data.length-1){
     stringBuilder.append("");
    }
   }
   return stringBuilder.toString();
  }
  
  /** 
      * 十六进制转换字符串
   * @param String str Byte字符串(Byte之间无分隔符 如:[616C6B])
   * @return String 对应的字符串
      */  
     public static String hexStr2Str(String hexStr)
     {  
         String str = "0123456789ABCDEF";  
         char[] hexs = hexStr.toCharArray();  
         byte[] bytes = new byte[hexStr.length() / 2];  
         int n;          for (int i = 0; i < bytes.length; i++)
         {  
             n = str.indexOf(hexs[2 * i]) * 16;  
             n += str.indexOf(hexs[2 * i + 1]);  
             bytes[i] = (byte) (n & 0xff);  
         }  
         return new String(bytes);  
     }
     
     /**
      * bytes转换成十六进制字符串
      * @param byte[] b byte数组
      * @return String 每个Byte值之间空格分隔
      */
     public static String byte2HexStr(byte[] b)
     {
         String stmp="";
         StringBuilder sb = new StringBuilder("");
         for (int n=0;n<b.length;n++)
         {
             stmp = Integer.toHexString(b[n] & 0xFF);
             sb.append((stmp.length()==1)? "0"+stmp : stmp);
             sb.append("");
         }
         return sb.toString().toUpperCase().trim();
     }
  
     /**
      * bytes字符串转换为Byte值
      * @param String src Byte字符串,每个Byte之间没有分隔符
      * @return byte[]
      */
     public static byte[] hexStr2Bytes(String src)
     {
         int m=0,n=0;
         int l=src.length()/2;
         System.out.println(l);
         byte[] ret = new byte[l];
         for (int i = 0; i < l; i++)
         {
             m=i*2+1;
             n=m+1;
             ret[i] = Byte.decode("0x" + src.substring(i*2, m) + src.substring(m,n));
         }
         return ret;
     }    /**
      * String的字符串转换成unicode的String
      * @param String strText 全角字符串
      * @return String 每个unicode之间无分隔符
      * @throws Exception
      */
     public static String strToUnicode(String strText)
      throws Exception
     {
         char c;
         StringBuilder str = new StringBuilder();
         int intAsc;
         String strHex;
         for (int i = 0; i < strText.length(); i++)
         {
             c = strText.charAt(i);
             intAsc = (int) c;
             strHex = Integer.toHexString(intAsc);
             if (intAsc > 128)
              str.append("\\u" + strHex);
             else // 低位在前面补00
              str.append("\\u00" + strHex);
         }
         return str.toString();
     }
     
     /**
      * unicode的String转换成String的字符串
      * @param String hex 16进制值字符串 (一个unicode为2byte)
      * @return String 全角字符串
      */
     public static String unicodeToString(String hex)
     {
         int t = hex.length() / 6;
         StringBuilder str = new StringBuilder();
         for (int i = 0; i < t; i++)
         {
             String s = hex.substring(i * 6, (i + 1) * 6);
             // 高位需要补上00再转
             String s1 = s.substring(2, 4) + "00";
             // 低位直接转
             String s2 = s.substring(4);
             // 将16进制的string转为int
             int n = Integer.valueOf(s1, 16) + Integer.valueOf(s2, 16);
             // 将int转换为字符
             char[] chars = Character.toChars(n);
             str.append(new String(chars));
         }
         return str.toString();
     }
     
     
     public static byte[] toByteArray(String hexString) {
   if (hexString == null)
    throw new IllegalArgumentException("this hexString must not be empty");  hexString = hexString.toLowerCase();
   final byte[] byteArray = new byte[hexString.length() / 2];
   int k = 0;
   for (int i = 0; i < byteArray.length; i++) {
             //因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先
    byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
    byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
    byteArray[i] = (byte) (high << 4 | low);
    k += 2;
   }
   return byteArray;
  }
     
  public static void main(String[] args){
   RSAEncrypt rsaEncrypt= new RSAEncrypt();
   
   //加载公钥
   try {
    rsaEncrypt.loadPublicKey(RSAEncrypt.DEFAULT_PUBLIC_KEY);
    
   } catch (Exception e) {
    System.err.println(e.getMessage());
    System.err.println("加载公钥失败");
   }
   
   //加载私钥
   try {
    rsaEncrypt.loadPrivateKey(RSAEncrypt.DEFAULT_PRIVATE_KEY);
    
   } catch (Exception e) {
    System.err.println(e.getMessage());
    System.err.println("加载私钥失败");
   }
   
   //测试字符串
   String encryptStr= "而广东统计局也表示,目前广东经济下行压力之大超乎年初预期,这既是复杂的国际经济环境影响的结果,也是广东主动调整经济结构、加快转型升级付出的代价。从上年一季度开始到今年一季度连续5个季度放缓后,今年上半年已经止跌并回升0.2个百分点,广东经济已开始筑底回稳。预计第三季度广东的经济运行将延续上半年的态势,在波动中略有回升,第四季度才会有较明显的好转。(中新网财经频道) (财经频道 李金磊)";  try {
    //加密
    byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(), encryptStr.getBytes());
    System.out.println(byte2HexStr(cipher));
    //
    String hexString = byte2HexStr(cipher);
    
    //System.out.println(new String(hexToBytes(hexString)));
    //解密
    byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), toByteArray(hexString));
    
    //System.out.println("密文长度:"+ cipher.length);
    //System.out.println(RSAEncrypt.byteArrayToString(cipher));
    /*
    System.out.println("明文长度:"+ plainText.length);
    System.out.println(RSAEncrypt.byteArrayToString(plainText));
    */
    System.out.println(new String(plainText));
    
   } catch (Exception e) {
    System.err.println(e.getMessage());
   }
  }
 }