RSA 非对称加解密算法

时间:2023-02-02 21:07:04
package com.007.common;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;

import javax.crypto.Cipher;

import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.Logger;

import sun.misc.BASE64Decoder;
import sun.security.util.DerInputStream;
import sun.security.util.DerValue;

import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.utils.Base64;

/**
 * 
 * @author 007
 * @date Jan 26, 2015 4:27:10 PM
 * @version V1.0
 * @Description: TODO(Rsa加密)
 * 
 */
public class RSAMain {
	private static Logger _log = Logger.getLogger(RSAMain.class);
	private PublicKey pubKey = null;
	private PrivateKey priKey = null;

	private static RSAMain rsaMain;

	/**
	 * 加密长度 用4096 做的key,选500 和选400分段长度 机密后的密文长度也有很大差距 选大的加密后密文短
	 * 
	 * 
	 * 1024:加密分段长度选100 解密长度选128
	 * 4096:加密分段长度选500 解密长度选512
	 * 
	 * 
	 */
	private RSAMain() {

		String keyinfo = "MIICXAIBAAKBgQDOxNnegpUXw4W9L+G92VgNuCsmFQYqRuOSVsue61KL2t6jVSTuxYqkanA6sCI9JzRspY8eAY6VRjcctAvEkBgLMRPgpIvw0Mv7JxxjDcm6nFE37+IdizKXlqv+cFgSjJhCGrM6JPK5K+kiyO7tyksdcAOyU8uIaqmEeVVCpv7oqwIDAQABAoGBAL11HfSGTjpyC08oWn3scoRPpinExdtjDQ5/vR+mnAJN0AZ089xc4QZ6CM+dqCHElIKgyJxD7PPWXJVOXCIFriCdWoQlA77JxXXTgHOpk74XCMJNlV+jKscr5jJGhFuyfI7VWEMIFddBpys3+xgzVo6YRlwDEnbEIEAUfIZqNQiBAkEA7AV/R34Bj2MQMW2KG2R81My0zr4LGxrxMNAKnJcUmjl0vIw53xGH00mSEMhMb/mYwNibYQk0NYLkR8946McLywJBAOBFdj8It6ZGKHjq4lnl3GO0uxpJhcUUfmyOErkh3bbJtyp4X7BB999/ddkpwjYHDxzPwWYF7PGnJjSfor/duqECQEehe3mFIpAT7qwxpIKfwssKva0pPFGjoaPA4BeaOqR735QBsuaieWiEoZH6WEh7pgKROsb+dhvvd7zbmMR89HUCQF4kCkzPZfe//4EyZ62A1ZBs7xVLw4FE5wS+ZpGb66us5NxJBzG/n0MMB/YOl12CfQ+FDhO7bQjLNzhjwjdz5cECQFcITAKCy4s4OStjdC5s7hx/9qKGQD0+Ih59gnd14a8btINUAf5VE0pSKnjh/bo6u2JCtsYGgoZpilNgLc7Kxnw="; //密钥信息用 BASE64 编码加密过,需要先解密

		String key4096pub = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA+O7xM/5YtSTNOhM+K0m0S2kYlTDV3YHz9pyOp5E1cFNLiJRglNslnZrRHDIW4jvXOES2WuHk5/x65mtsm44ccuhY6pnjgDU87Du8HNoT/4x290KgjtfxZedZF2zzBSl9Q2kkRe+erJWA7+J22AUKv0Kyfkh64l+wgvoTR/UCcd1C/qil9QeFutOMt8zkmFDp47jcDA6EkPfaOfCEAJboql84tp1AAMgo6o10lgR8XN9UuyLRVT4NvpTJhEZufNqLWfGVqwQjODRIUA/57CDBWSfak1N36za+w7V9Ng+tO1aL2Uhw1UbpkW4slnUfb02BNEdTnVBImTfTGmM1b9k4kuZu5Kx9mV5sK7ztF6qWvpKiduwfg1ap1N/BNJ3h7SrFVQi1SElG1diZIHu1mf118GMCex04BOY8mYeMANq7EjNfBh8AN2ggdyLr2kZqHjIGlg77wnQqpzpJgYcFhfm6nodqMKUJ0r2Q2uOEM+teDk+DLYblygcVLCIm+l0gAWF7gWSFqrgk5gdqt8Spk1/BC5njkhFAo2CcWWhOnYpQBVRsV4/96Rd5v7y0MCIngdTg3o+18bnkR6/el3aYZawOzfmvgcOP7lr0yf0eU9iGDS74UQTykYuH7zDjx4fyvQA6ASrornJzPpdf+wK9B0WBp3o5qR1BA2xRyorpmJ+EpK0CAwEAAQ==";

		String pubkey4096data = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA+O7xM/5YtSTNOhM+K0m0" + "\r"
				+ "S2kYlTDV3YHz9pyOp5E1cFNLiJRglNslnZrRHDIW4jvXOES2WuHk5/x65mtsm44c" + "\r"
				+ "cuhY6pnjgDU87Du8HNoT/4x290KgjtfxZedZF2zzBSl9Q2kkRe+erJWA7+J22AUK" + "\r"
				+ "v0Kyfkh64l+wgvoTR/UCcd1C/qil9QeFutOMt8zkmFDp47jcDA6EkPfaOfCEAJbo" + "\r"
				+ "ql84tp1AAMgo6o10lgR8XN9UuyLRVT4NvpTJhEZufNqLWfGVqwQjODRIUA/57CDB" + "\r"
				+ "WSfak1N36za+w7V9Ng+tO1aL2Uhw1UbpkW4slnUfb02BNEdTnVBImTfTGmM1b9k4" + "\r"
				+ "kuZu5Kx9mV5sK7ztF6qWvpKiduwfg1ap1N/BNJ3h7SrFVQi1SElG1diZIHu1mf11" + "\r"
				+ "8GMCex04BOY8mYeMANq7EjNfBh8AN2ggdyLr2kZqHjIGlg77wnQqpzpJgYcFhfm6" + "\r"
				+ "nodqMKUJ0r2Q2uOEM+teDk+DLYblygcVLCIm+l0gAWF7gWSFqrgk5gdqt8Spk1/B" + "\r"
				+ "C5njkhFAo2CcWWhOnYpQBVRsV4/96Rd5v7y0MCIngdTg3o+18bnkR6/el3aYZawO" + "\r"
				+ "zfmvgcOP7lr0yf0eU9iGDS74UQTykYuH7zDjx4fyvQA6ASrornJzPpdf+wK9B0WB" + "\r" + "p3o5qR1BA2xRyorpmJ+EpK0CAwEAAQ==";

		String prikey4096data = "MIIJKQIBAAKCAgEA+O7xM/5YtSTNOhM+K0m0S2kYlTDV3YHz9pyOp5E1cFNLiJRglNslnZrRHDIW4jvXOES2WuHk5/x65mtsm44ccuhY6pnjgDU87Du8HNoT/4x290KgjtfxZedZF2zzBSl9Q2kkRe+erJWA7+J22AUKv0Kyfkh64l+wgvoTR/UCcd1C/qil9QeFutOMt8zkmFDp47jcDA6EkPfaOfCEAJboql84tp1AAMgo6o10lgR8XN9UuyLRVT4NvpTJhEZufNqLWfGVqwQjODRIUA/57CDBWSfak1N36za+w7V9Ng+tO1aL2Uhw1UbpkW4slnUfb02BNEdTnVBImTfTGmM1b9k4kuZu5Kx9mV5sK7ztF6qWvpKiduwfg1ap1N/BNJ3h7SrFVQi1SElG1diZIHu1mf118GMCex04BOY8mYeMANq7EjNfBh8AN2ggdyLr2kZqHjIGlg77wnQqpzpJgYcFhfm6nodqMKUJ0r2Q2uOEM+teDk+DLYblygcVLCIm+l0gAWF7gWSFqrgk5gdqt8Spk1/BC5njkhFAo2CcWWhOnYpQBVRsV4/96Rd5v7y0MCIngdTg3o+18bnkR6/el3aYZawOzfmvgcOP7lr0yf0eU9iGDS74UQTykYuH7zDjx4fyvQA6ASrornJzPpdf+wK9B0WBp3o5qR1BA2xRyorpmJ+EpK0CAwEAAQKCAgEAs78FF7/+mb4bGmYuq98qepFGmOOMaceeO2JMd56YcaUTk2lgW9vpy2WwvKVGdNE01IJ5EiKuwPxEWgETiTcSP76aBbxc04Sdmw5/BG5Lpmjsthm8CajPu/9TC2E2EXIl6vkOohkmAARr98sUeWMaoYQtkpYPdUoXEFw2c+zseP+FkpCAVO+7lm2O3GDsZzd1y2L+MQ6ClpMBVnjfN/W/xtW/A82EG4xsTwEZQAG5Mu5oJkA720tVbVnOMN8ShMDhgm643aW9MKY/2N/QXLpCInhukZbhrkv3byWrZc/oDEKv9JMkNjxgBw0A0Rt9OUdDllYygBMqeMggfJtKSJsXBz8ai9ciZerLvU9sVeGwRIvx4XHOuDOlXBZjMUl+yzT6MvPL2j363qWZ2Y5nyJ0Q3r5y79MK1q4OcnxN6CejaVVuNTWgZb4bS6aij2YM0cxmLKuxcA6JspDQZOzxMjc73ESVU4J5wPyQEW119TPjJHFt1x0qR/AgbDpYaVc3+8MwML2k9Ayjbeu55DxvcHH63jz1s9AK9+dhOmZn5JQpdgFsbxUaMVSTN91WMD/tBL8OEJVl2EyQ5clj6gS5KMw/JTzZnW/yeGnjx0dYk9ROS7DtgelJERYYDflYK8iNvqKzeGQC9V5zG+5dTmlw0vvPGcRnfn6Kdfb9TklvItXB6VkCggEBAP82XxxKKsghsk8dvkWxlD+EHudFmPw3YPM2L/mOMUnDMKlo1xATMnzH01bzQW9PvTVt3jkQMn1bAC05qgQtgJXYjqxcNGvjjKBgWTa2GDbuBXYW0kH2kEX0Aw+fi4lgNLr9zz7cXywBY0GWDS+wFpYCvo2Nr4huLgAjuiY1yqvtGLN3NfuY/rCkb8wHTAqX0lVS4tt3bMoB5JB8f+e170mqjBsAmDGuqw4zuzIR1auUHz4KIXsEWxd5V2C0Ui6HJg2ypjzVw2RqskmqckJgKbmMOCmtVEwZji54CZ6bIO2mIIp0BVGUZ+eEXMC1aVh4qzJJ3xddIl6P9Pu10KXPy/MCggEBAPmznCf28gFGogGujx+jiHP/JMpT5PPQ1SvD5eDcmL/RP8nz6r+25ZUMzWK52NvpZTjNU8BnhIw7ti7FZCYGRtDNItRXwmEfxQgWuqv9VkmPHnlVT5S0mP27HLG5v1GgGrSk8btzL5wSPhjW/na8Y2Wo8FDKYkIav5/fVPJYOJMbdoqd0OCkpRL7CYT0IlgNtWPVdbHveKOwVanLBg8nVWr2KIoifUvyrYEEL7QKWge490I6utIfG64fZyPzLAKyTyXeDYlNgXaC5vE4z6zsH43pPdraof4bk7Z9J7YdTswe29YoB5BqtgENLZcsJus9FWgTFppqO5rj/ATH40HhFN8CggEBAJe5iV3WMgz9C3bBpgblBc+lCoJP/B2mBrtQ8cCZanAB3QI6U/E4mIFagyhkQfidHU2QXdbq7DleSoKYj50gOBvdvSR3RKsHguktnpxKMacmZpTICIQyw57y7IbzQQ+Q5IhusDEc7m/I+2tYe8poE2VniEW7gCnJ5wsqMlbZD/6aXF8FdlB3qqL1f4l6pRh/Hgqf1kLHgyOtcGb9vUTSAsp23AiJl/GheAxfcODZfYAd9Vz6xODPvB/+gZX6XglPS65FEVOFej5OuGPXM0qGxQeMdy8/3qfHYaH6ty1V6IOgiiQFycuwQP2A0Wu37kMsqgqhpEHNmstBJlImyz5ohUUCggEABVppZZ3wsEBQZtLUNKxv13TH2CKWTPfUKh0IB5sTF0GoKW82QCfuohRlLtGnKYfGaMJWIlDV0Z/SFwyaSgpmaEGNlpnPC///XF4IYHmM6QTNdXJzw09f3Eivo8vEoz5YdDj5Cbi9c44ckLHDQM5nHx3RERpVou8p3oaOLqffhp/XGb+qY7aD53VETfph5htdISfJXygwIOo92+cDWT3RofpnAhcdMoygVZy+XRC/v1yiyGOz759FG6WGs4maDvC9q6UoCyKDPQQvaUp7gUyKnKM8dT2srWLv9sCWIlxcfRnIQr4W82ymPD2JFa2XpAFqPRHzsRnH71kl5QBYCeiGZwKCAQBBlxZHP00f7OJc57ckIZRqF/4Y4YtroOL+Ap4C3zUsMTnEMYEmQeijx7haSrK8Ld6yTb+naqrqLBWC4z/d25ly0P0CaIJpbZkLMw/fR/hSdNU99raPG6osR1aZoMySn7yhq8jLUGLNBH+omAsNjpA5frClIxFAPktv/B0e6EFCNaZk4p6eoEI2EhwQ1bxWqLisCywTasu1ohO6jpjDYtIQX/oBm7yqh1It2PHPpC9WAXAwE6LnDRsaz+UVeTOCFKeNq109vcw1kl3M/X0iu/ONKmoaZ0QkkAF3Ltid89i2ylhTRJivjg2/uCHjq5Z6Q3/lvTRCjEyZrdVxZuDS9Oll";

		String pkcs8prikey4096data = "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" + "IeOrlnpDf+W9NEKMTJmt1XFm4NL06WU=";

		/**
		 * 方式一
		 * 
		 * http://www.cnblogs.com/Athrun/p/3781508.html
		 * 
		 * 生成一个密钥(私钥)
		 * 
		 * [root@hunterfu ~]# openssl genrsa -out private.key 4096
		 * 
		 * 注意: 需要注意的是这个文件包含了公钥和密钥两部分,也就是说这个文件即可用来加密也可以用来解密,后面的1024是生成
		 * 
		 * 密钥的长度.
		 * 
		 * 通过密钥文件private.key 提取公钥
		 * 
		 * [root@hunterfu ~]# openssl rsa -in private.key -pubout -out pub.key
		 * 
		 * 使用公钥加密信息
		 * 
		 * [root@hunterfu ~]# echo -n "123456" | openssl rsautl -encrypt -inkey pub.key -pubin >encode.result
		 * 
		 * 使用私钥解密信息
		 * 
		 * [root@hunterfu ~]#cat encode.result | openssl rsautl -decrypt -inkey private.key
		 * 123456
		 */

		//根据私钥生成私钥公钥
		initRSAKEY(prikey4096data);

		/**
		 * 方式二
		 * http://blog.csdn.net/chaijunkun/article/details/7275632
		 * 
		 * openssl genrsa -out rsa_private_key.pem 4096
		 * 
		 * openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout
		 * 
		 * 这时候的私钥还不能直接被使用,需要进行PKCS#8编码
		 * 
		 * openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt
		 * 
		 */
		//根据openssl生产的公钥加载公钥
		//loadPublicKey(pubkey4096data);

		//根据openssl生产的私钥,经过PKCS#8编码后的私钥数据,加载私钥
		//loadPrivateKey(pkcs8prikey4096data);

		//		String privateKeyPath="";
		//		initRSAKEY(new File(privateKeyPath));
	}

	/**
	 * 从字符串中加载公钥
	 * 
	 * @param publicKeyStr
	 *            公钥数据字符串
	 * @throws Exception
	 *             加载公钥时产生的异常
	 */
	public void loadPublicKey(String publicKeyStr) {
		try {
			BASE64Decoder base64Decoder = new BASE64Decoder();
			byte[] buffer = base64Decoder.decodeBuffer(publicKeyStr);
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
			pubKey = 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("公钥数据为空");
		}
	}

	public void loadPrivateKey(String privateKeyStr) {
		try {
			BASE64Decoder base64Decoder = new BASE64Decoder();
			byte[] buffer = base64Decoder.decodeBuffer(privateKeyStr);
			PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			priKey = 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("私钥数据为空");
		}
	}

	public static RSAMain getInstance() {
		if (rsaMain == null) {
			rsaMain = new RSAMain();
		}
		_log.debug("getInstance rsaMain is " + rsaMain == null ? "null!" : "not null!");
		return rsaMain;
	}

	public String encryptAndBase64(String str) {
		return Base64.encode(encrypt(str));
	}

	public String base64AndDencrypt(String str) throws Base64DecodingException {
		return Dencrypt(Base64.decode(str));
	}

	/**
	 * 加密成二进制
	 * 
	 * @param str
	 * @return
	 */
	public byte[] encrypt(String str) {
		try {
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.ENCRYPT_MODE, pubKey);

			byte[] data = new String(str).getBytes();
			byte[] enBytes = null;
			for (int i = 0; i < data.length; i += 500) { // 注意要使用2的倍数,否则会出现加密后的内容再解密时为乱码  
				byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + 500));
				enBytes = ArrayUtils.addAll(enBytes, doFinal);
			}
			return enBytes;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;

	}

	/**
	 * 解密二进制
	 * 
	 * @param encrypted
	 * @return
	 */
	public String Dencrypt(byte[] encrypted) {
		try {
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, priKey);
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < encrypted.length; i += 512) {
				byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(encrypted, i, i + 512));
				sb.append(new String(doFinal));
			}
			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private void initRSAKEY(String keyinfo) {
		byte[] decodeKeyinfo;
		try {
			decodeKeyinfo = (new BASE64Decoder()).decodeBuffer(keyinfo);
			DerInputStream dis = new DerInputStream(decodeKeyinfo); //密钥不含 otherPrimeInfos 信息,故只有 9 段 
			DerValue[] ders = dis.getSequence(9); //依次读取 RSA 因子信息 
			int version = ders[0].getBigInteger().intValue();
			BigInteger modulus = ders[1].getBigInteger();
			//System.out.println("modulus=" + modulus);
			BigInteger publicExponentb = ders[2].getBigInteger();
			//System.out.println("publicExponentb=" + publicExponentb);
			BigInteger privateExponentb = ders[3].getBigInteger();
			BigInteger primeP = ders[4].getBigInteger();
			BigInteger primeQ = ders[5].getBigInteger();
			BigInteger primeExponentP = ders[6].getBigInteger();
			BigInteger primeExponentQ = ders[7].getBigInteger();
			BigInteger crtCoefficient = ders[8].getBigInteger();
			//generate public key and private key
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, publicExponentb);
			PublicKey publicKey = keyFactory.generatePublic(rsaPublicKeySpec);
			RSAPrivateCrtKeySpec rsaPrivateKeySpec = new RSAPrivateCrtKeySpec(modulus, publicExponentb, privateExponentb, primeP, primeQ,
					primeExponentP, primeExponentQ, crtCoefficient);
			PrivateKey privateKey = keyFactory.generatePrivate(rsaPrivateKeySpec);
			pubKey = publicKey;
			priKey = privateKey;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		}

	}

	private void initRSAKEY(File file) {
		//		File file = new File("F:/工作任务/19IM群/private.key");
		try {
			BufferedReader br = new BufferedReader(new FileReader(file));
			String keyinfo = "";
			String line = null; //去掉文件头尾的注释信息 
			while ((line = br.readLine()) != null) {
				if (line.indexOf("---") == -1) {
					keyinfo += line;
				}
			}
			byte[] decodeKeyinfo = (new BASE64Decoder()).decodeBuffer(keyinfo); //使用 DerInputStream 读取密钥信息 
			DerInputStream dis = new DerInputStream(decodeKeyinfo); //密钥不含 otherPrimeInfos 信息,故只有 9 段 
			DerValue[] ders = dis.getSequence(9); //依次读取 RSA 因子信息 
			int version = ders[0].getBigInteger().intValue();
			BigInteger modulus = ders[1].getBigInteger();
			BigInteger publicExponentb = ders[2].getBigInteger();
			BigInteger privateExponentb = ders[3].getBigInteger();
			BigInteger primeP = ders[4].getBigInteger();
			BigInteger primeQ = ders[5].getBigInteger();
			BigInteger primeExponentP = ders[6].getBigInteger();
			BigInteger primeExponentQ = ders[7].getBigInteger();
			BigInteger crtCoefficient = ders[8].getBigInteger();
			//generate public key and private key
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, publicExponentb);
			PublicKey publicKey = keyFactory.generatePublic(rsaPublicKeySpec);
			RSAPrivateCrtKeySpec rsaPrivateKeySpec = new RSAPrivateCrtKeySpec(modulus, publicExponentb, privateExponentb, primeP, primeQ,
					primeExponentP, primeExponentQ, crtCoefficient);
			PrivateKey privateKey = keyFactory.generatePrivate(rsaPrivateKeySpec);
			//		publicModule = modulus.toString();
			//		publicExponent = publicExponentb.toString();
			//		priviteExponent = privateExponentb.toString();
			pubKey = publicKey;
			priKey = privateKey;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		}

	}

	public static RSAPublicKey decodePublicKey(byte[] key) {
		byte[] sshrsa = new byte[] { 0, 0, 0, 7 };
		int start_index = sshrsa.length;
		/* Decode the public exponent */
		int len = decodeUInt32(key, start_index);
		start_index += 4;
		byte[] pe_b = new byte[len];
		for (int i = 0; i < len; i++) {
			pe_b[i] = key[start_index++];
		}
		BigInteger pe = new BigInteger(pe_b);
		/* Decode the modulus */
		len = decodeUInt32(key, start_index);
		start_index += 4;
		byte[] md_b = new byte[len];
		for (int i = 0; i < len; i++) {
			md_b[i] = key[start_index++];
		}
		BigInteger md = new BigInteger(md_b);
		KeyFactory keyFactory;
		RSAPublicKey publicKey = null;
		try {
			keyFactory = KeyFactory.getInstance("RSA");
			KeySpec ks = new RSAPublicKeySpec(md, pe);
			publicKey = (RSAPublicKey) keyFactory.generatePublic(ks);
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return publicKey;
	}

	public static int decodeUInt32(byte[] key, int start_index) {
		byte[] test = Arrays.copyOfRange(key, start_index, start_index + 4);
		return new BigInteger(test).intValue();
		//	      int int_24 = (key[start_index++] << 24) & 0xff;  
		//	      int int_16 = (key[start_index++] << 16) & 0xff;  
		//	      int int_8 = (key[start_index++] << 8) & 0xff;  
		//	      int int_0 = key[start_index++] & 0xff;  
		//	      return int_24 + int_16 + int_8 + int_0;  
	}

	/**
	 * @param args
	 * @throws Base64DecodingException
	 * @throws IOException
	 * @throws InvalidKeySpecException
	 * @throws NoSuchAlgorithmException
	 */
	public static void main(String[] args) throws Base64DecodingException, NoSuchAlgorithmException, InvalidKeySpecException, IOException {

		System.out.println("start...");
		RSAMain rsaMain = RSAMain.getInstance();
		String teststr = "计算机<root><f><fn>>微软雅黑</fn><fs>10</fs><fe>0</fe><fc>0</fc></f><c><t>1</t><txt><![CDATA[\r"
				+ "]]></txt></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><t>1</t><txt><![CDATA[\r"
				+ "]]></txt></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><t>1</t><txt><![CDATA[\r"
				+ "]]></txt></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c><c><id>1.0.86.gif</id><t>2</t></c></root>\r";
		long s = System.currentTimeMillis();
		for (int i = 0; i < 1; i++) {

			String miwen = rsaMain.encryptAndBase64(teststr);
			//System.out.println("miwen=" + miwen);
			System.out.println(rsaMain.base64AndDencrypt(miwen));
		}
		//System.out.println(teststr.length());
		//System.out.println((System.currentTimeMillis() - s));
	}

}