RSA java 加密长文本

整理网络资源来的,稍微做了修改
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
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 javax.crypto.ShortBufferException;

public class Encryptor {
	public static final String KEY_FILENAME = "E:\\test\\mykey.dat";
	public static final String OTHERS_KEY_FILENAME = "E:\\test\\Otherskey.dat";
	private static final int KEY_SIZE = 2048; // RSA key 是多少位的
	private static final int BLOCK_SIZE = 245; // 一次RSA加密操作所允许的最大长度
	// 这个值与 KEY_SIZE 已经padding方法有关。因为 1024的key的输出是128,2048key输出是256字节
	// 可能11个字节用于保存padding信息了,所以最多可用的就只有245字节了。
	private static final int OUTPUT_BLOCK_SIZE = 256;
	private static SecureRandom secrand;


	/*
	 * 生成自己的公钥和私钥
	 */
	public static Boolean GenerateKeys() {
		try {
			KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
			
			SecureRandom secrand = new SecureRandom();
			
			// secrand = new SecureRandom();
			// sedSeed之后会造成 生成的密钥都是一样的
			// secrand.setSeed("chatencrptor".getBytes()); // 初始化随机产生器
			// key长度至少512长度,不过好像说现在用2048才算比较安全的了
			keygen.initialize(KEY_SIZE, secrand); // 初始化密钥生成器
			KeyPair keys = keygen.generateKeyPair(); // 生成密钥组
			
			SaveKeys(keys.getPrivate(),KEY_FILENAME);
			SaveKeys(keys.getPublic(),OTHERS_KEY_FILENAME);
			
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return false;
		}
		
		return true;
	}

	public static String EncryptMessage(Key pubkey, String Message){
		
		try {
			
			Cipher rsaCipher = Cipher.getInstance("RSA/ECB/NOPADDING");
			
			rsaCipher.init(Cipher.ENCRYPT_MODE, pubkey, secrand);

			byte[] data = Message.getBytes("utf-8");
			int blocks = data.length / BLOCK_SIZE;
			int lastBlockSize = data.length % BLOCK_SIZE;
			byte[] encryptedData = new byte[(lastBlockSize == 0 ? blocks
					: blocks + 1) * OUTPUT_BLOCK_SIZE];
			for (int i = 0; i < blocks; i++) {
				rsaCipher.doFinal(data, i * BLOCK_SIZE, BLOCK_SIZE,
						encryptedData, i * OUTPUT_BLOCK_SIZE);
			}
			if (lastBlockSize != 0) {
				rsaCipher.doFinal(data, blocks * BLOCK_SIZE, lastBlockSize,
						encryptedData, blocks * OUTPUT_BLOCK_SIZE);
			}
			// System.out.println(encrypted.length);
			// 如果要机密的数据不足128/256字节,加密后补全成为变为256长度的。
			// 数量比较小时,Base64.GZIP产生的长度更长,没什么优势
			// System.out.println(Base64.encodeBytes(encrypted,Base64.GZIP).length());
			// System.out.println(Base64.encodeBytes(encrypted).length());
			// System.out.println (rsaCipher.getOutputSize(30));
			// 这个getOutputSize 只对 输入小于最大的block时才能得到正确的结果。其实就是补全 数据为128/256 字节
			return Base64.encodeBytes(encryptedData);
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (ShortBufferException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} finally {
			// catch 中 return 或者throw之前都会先调用一下这里
		}
		
		return null;
		
	}

	public static String DecryptMessage(Key prikey,String Message) {
		
		try {
			
			byte[] decoded = Base64.decode(Message);
			
			Cipher rsaCipher = Cipher.getInstance("RSA/ECB/NOPADDING");
			rsaCipher.init(Cipher.DECRYPT_MODE, prikey, secrand);
			int blocks = decoded.length / OUTPUT_BLOCK_SIZE;
			ByteArrayOutputStream decodedStream = new ByteArrayOutputStream(
					decoded.length);
			for (int i = 0; i < blocks; i++) {
				decodedStream.write(rsaCipher.doFinal(decoded, i
						* OUTPUT_BLOCK_SIZE, OUTPUT_BLOCK_SIZE));
			}
			return new String(decodedStream.toByteArray(), "UTF-8");
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// catch 中 return 或者throw之前都会先调用一下这里。
		}
		return null;
	}


	public static String loadKeys(String path) {
		BufferedReader input;
		try {
			input = new BufferedReader(new InputStreamReader(
					new FileInputStream(path)));
		} catch (FileNotFoundException e1) {
			return "";
		}
		String line;
		StringBuffer sb = new StringBuffer();
		try {
			while ((line = input.readLine()) != null) {
				sb.append(line);
			}
		} catch (Exception e) {
			return "";
		} finally {
			try {
				input.close();
			} catch (Exception e) {
				return "";
			}
		}
		return sb.toString();
	}

	public static boolean SaveKeys(Key key,String path) {
		FileWriter output;
		try {
			output = new FileWriter(path);
		} catch (IOException e1) {
			return false;
		}
		
		try {
			output.write(EncodeKey(key));
		} catch (IOException e1) {
			return false;
		} finally {
			try {
				output.close();
			} catch (Exception e) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 解密base64编码得到公钥
	 * 
	 * @param key
	 *            密钥字符串(经过base64编码)
	 * @throws Exception
	 */
	public static PublicKey DecodePublicKey(String key) throws Exception {
		byte[] keyBytes;
		keyBytes = Base64.decode(key);
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PublicKey publicKey = keyFactory.generatePublic(keySpec);
		return publicKey;
	}

	/**
	 * 解密base64编码得到私钥
	 * 
	 * @param key
	 *            密钥字符串(经过base64编码)
	 * @throws Exception
	 */
	public static PrivateKey DecodePrivateKey(String key) throws Exception {
		byte[] keyBytes;
		keyBytes = Base64.decode(key);
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
		return privateKey;
	}

	/**
	 * 编码key为base64字符串
	 * 
	 * @return
	 */
	public static String EncodeKey(Key key) {
		byte[] keyBytes = key.getEncoded();
		String s = Base64.encodeBytes(keyBytes);
		return s;
	}
}

测试方法:

public static void main(String[] args) {
		SimpleDateFormat format = new SimpleDateFormat("yyy-MM-DD HH-mm-ss sss");
		try {
			String srcStr = "aaaaa";
			System.out.println("srcStr:" + srcStr);
			System.out.println("start--createKey:"+format.format(new Date()));
			Encryptor.GenerateKeys();
			System.out.println("stop--createKey:"+format.format(new Date()));
			String priKeyStr = Encryptor.loadKeys(Encryptor.KEY_FILENAME);
			System.out.println("priKeyStr:"+priKeyStr+",\n"+format.format(new Date()));
			String pubKeyStr = Encryptor.loadKeys(Encryptor.OTHERS_KEY_FILENAME);
			System.out.println("pubKeyStr:"+pubKeyStr+",\n"+format.format(new Date()));
			
			PrivateKey priKey = Encryptor.DecodePrivateKey(priKeyStr);
			
			System.out.println("decode-prikey:"+format.format(new Date()));
			PublicKey pubKey = Encryptor.DecodePublicKey(pubKeyStr);
			
			
			System.out.println("decode-pubkey:"+format.format(new Date()));
			
			String enStr = Encryptor.EncryptMessage(pubKey, srcStr);
			System.out.println("enStr:" + enStr+",\n:"+format.format(new Date()));

			String deStr = Encryptor.DecryptMessage(priKey,enStr);
			System.out.println("deStr:"+deStr+",\n:"+format.format(new Date()));
			

		} catch (Exception e) {
			e.printStackTrace();
		}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值