RSA算法加解密(JAVA)

/**
 * RSA加密算法的演示验证
 * RSA是一种分组加密算法
 * 注意:密钥对采用的长度决定了加密块的长度,我这里取的是2048,即256byte
 * 由于加密块的长度固定为256,因此明文的长度至多为256 - 11 = 245byte
 * 我这里明文长度取的是128byte,密文长度为256byte,它适合于小文件加密
 */
package encrypto;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
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.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;

/**
 * @author liuhuabai,liuhuabai@163.com
 *
 */
public class RSADemo {
	/**
	 * 公钥
	 */
	private RSAPublicKey publicKey;
	/**
	 * 私钥
	 */
	private RSAPrivateKey privateKey;
	/**
	 * 用于加解密
	 */
	private Cipher cipher;
	/**
	 * 明文块的长度 它必须小于密文块的长度 - 11
	 */
	private int originLength = 128;
	/**
	 * 密文块的长度
	 */
	private int encrytLength = 256;
	
	/**
	 * 得到初始化的公钥和私钥
	 * @throws NoSuchAlgorithmException 
	 * @throws NoSuchPaddingException 
	 */
	public void initKey() throws NoSuchAlgorithmException, NoSuchPaddingException {
		//RSA加密算法:创建密钥对,长度采用2048
		KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");
		kg.initialize(encrytLength * 8);
		KeyPair keypair = kg.generateKeyPair();
		//分别得到公钥和私钥
		publicKey = (RSAPublicKey) keypair.getPublic();
		privateKey = (RSAPrivateKey) keypair.getPrivate();
	}
	/**
	 * 将公钥保存至文件
	 * @param file 待写入的文件
	 * @return true 写入成功;false 写入失败
	 */
	public boolean savePublicKey(File file) {
		return this.saveKey(publicKey, file);
	}
	/**
	 * 将私钥保持至文件
	 * @param file 待写入的文件
	 * @return true 写入成功;false 写入失败
	 */
	public boolean savePrivateKey(File file) {
		return this.saveKey(privateKey, file);
	}
	//将Key文件保持到文件中
	private boolean saveKey(Key key,File file) {
		boolean write;
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(file);
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			//System.out.println(key.getFormat());
			//公钥默认使用的是X.509编码,私钥默认采用的是PKCS #8编码
			byte [] encode = key.getEncoded();
			//注意,此处采用writeObject方法,读取时也要采用readObject方法
			oos.writeObject(encode);
			write = true;
		} catch (IOException e) {
			write = false;
		} finally {
				try {
					if(fos != null) fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
		return write;
	}
	/**
	 * 从文件中得到公钥
	 * @param file 保存公钥的文件
	 */
	public void getPublicKey(File file) {
		getKey(file,0);
	}
	/**
	 * 从文件中得到私钥
	 * @param file 保存私钥的文件
	 */
	public void getPrivateKey(File file) {
		getKey(file,1);
	}
	
	private void getKey(File file,int mode) {
		FileInputStream fis;
		try {
			//读取数据
			fis = new FileInputStream(file);
			ObjectInputStream ois = new ObjectInputStream(fis);
			byte [] keybyte = (byte[]) ois.readObject();
			//关闭资源
			ois.close();
			//默认编码
			KeyFactory keyfactory = KeyFactory.getInstance("RSA");
			//得到公钥或是私钥
			if(mode == 0) {
				X509EncodedKeySpec x509eks= new X509EncodedKeySpec(keybyte);
				publicKey = (RSAPublicKey) keyfactory.generatePublic(x509eks);
				//System.out.println(pk.getAlgorithm());
			} else {
				PKCS8EncodedKeySpec pkcs8eks = new PKCS8EncodedKeySpec(keybyte);
				privateKey = (RSAPrivateKey) keyfactory.generatePrivate(pkcs8eks);
				//System.out.println(pk.getAlgorithm());
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}		
	}

	/**
	 * 数据RSA加密
	 * @param origin 明文
	 * @return 密文
	 */
	protected byte [] encrypt(byte [] origin) {
		//byte [] enc = new byte [encrytLength];
		byte [] enc = null;
		try {
			cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.ENCRYPT_MODE, publicKey);
			enc = cipher.doFinal(origin);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return enc;
	}
	/**
	 * 数据RSA解密
	 * @param enc 密文
	 * @return 明文
	 */
	protected byte [] decrypt(byte [] enc) {
		//byte [] origin = new byte [originLength];
		byte [] origin = null;
		try {
			cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, privateKey);
			origin = cipher.doFinal(enc);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return origin;
	}
	/**
	 * 加密文件
	 * @param origin 明文件
	 * @throws IOException
	 */
	public void encryptFile(File origin) throws IOException {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		
		//读入
		fis = new FileInputStream(origin);
		BufferedInputStream bis = new BufferedInputStream(fis);
		byte [] originbyte = new byte [originLength];
		//写出
		fos = new FileOutputStream(new File(origin+".encrypt"));
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		byte [] encryptbyte;
		//int k;
		while(bis.read(originbyte) > 0) {
			encryptbyte = this.encrypt(originbyte);
			bos.write(encryptbyte);
			originbyte = new byte[originLength];
		}
		//压入
		bos.flush();
		//关闭资源
		if(fis != null) fis.close();
		if(fos != null) fos.close();		
	}
	/**
	 * 解密文件
	 * @param encrypt 密文件
	 * @throws IOException
	 */
	public void decryptFile(File encrypt) throws IOException {
		
		FileInputStream fis = null;
		FileOutputStream fos = null;
		//读入
		fis = new FileInputStream(encrypt);
		BufferedInputStream bis = new BufferedInputStream(fis);
		byte [] encryptbyte = new byte [encrytLength];
		//写出
		fos = new FileOutputStream(new File(encrypt+".decrypt"));
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		byte [] originbyte;
		
		//int k;
		while(bis.read(encryptbyte) > 0) {
			originbyte = this.decrypt(encryptbyte);
			bos.write(originbyte);
			encryptbyte = new byte [encrytLength];
		}
		//压入
		bos.flush();
		//关闭资源
		if(fis != null) fis.close();
		if(fos != null) fos.close();
	}
	
	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws Exception {
		RSADemo rsa = new RSADemo();
		rsa.initKey();
		rsa.encryptFile(new File("E:/hello.txt"));
		rsa.decryptFile(new File("E:/hello.txt.encrypt"));
		rsa.savePublicKey(new File("E:/public.key"));
		rsa.savePrivateKey(new File("E:/private.key"));
		//rsa.getPublicKey(new File("E:/public.key"));
		//rsa.getPrivateKey(new File("E:/private.key"));
		//rsa.encryptFile(new File("E:/hello.txt"));
		//rsa.decryptFile(new File("E:/hello.txt.encrypt"));
	}
}


 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值