码迷,mamicode.com
首页 > 编程语言 > 详细

Java非对称加密算法--RSA加密算法

时间:2015-03-17 18:00:04      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:非对称加密解密   security   java   rsa   

Java非对称加密算法--RSA加密算法

         RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。

1973年,在英国政府通讯总部工作的数学家克利福德·柯克斯(Clifford Cocks)在一个内部文件中提出了一个相同的算法,但他的发现被列入机密,一直到1997年才被发表。

         对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式解破。到2013年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。

         下面我是采用Bouncy Castle实现的RSA加密算法。Bouncy Castle 是一种用于 Java 平台的开放源码的轻量级密码术包。它支持大量的密码术算法,并提供 JCE 1.2.1 的实现。因为 Bouncy Castle 被设计成轻量级的,所以从 J2SE 1.4 到 J2ME(包括 MIDP)平台,它都可以运行。它是在 MIDP 上运行的唯一完整的密码术包。

<span style="font-size:14px;">package com.qiuzhping.rsa;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
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 javax.crypto.Cipher;

/**
 * 非对称加密是公钥加密,私钥来解密.使用的是Bouncy Castle 是一种用于 Java 平台的开放源码的轻量级密码术包.
 * 1、此Demo使用的是bcprov-ext-jdk15on-152.jar 
 * 2、把jar文件复制到 $JAVA_HOME$\jre\lib\ext目录下面
 * 3、修改配置文件\jre\lib\security\java.security
 * security.provider.1=sun.security.provider.Sun
 * security.provider.2=sun.security.rsa.SunRsaSign
 * security.provider.3=com.sun.net.ssl.internal.ssl.Provider
 * security.provider.4=com.sun.crypto.provider.SunJCE
 * security.provider.5=sun.security.jgss.SunProvider
 * security.provider.6=com.sun.security.sasl.Provider
 * security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI
 * security.provider.8=sun.security.smartcardio.SunPCSC 上述8个是JDK已经实现了的加密方式. 将
 * security.provider.9=org.bouncycastle.jce.provider.BouncyCastleProvider 添加到后面.
 * 非对称加密称为公钥加密,算法更加复杂,速度慢,加密和解密钥匙不相同,任何人都可以知道公钥,只有一个人持有私钥可以解密。
 * 
 * @author Peter.Qiu
 * 
 */
public class RsaUtil {

	/**
	 * 根据publicKey 对data进行加密.
	 * 
	 * @param publicKey
	 * @param data
	 * @throws Exception
	 * @author Peter.Qiu
	 */
	public static byte[] encryptMode(PublicKey publicKey, byte[] data)
			throws Exception {
		try {
			Cipher cipher = Cipher.getInstance("RSA",
					new BouncyCastleProvider());
			cipher.init(Cipher.ENCRYPT_MODE, publicKey);// ENCRYPT_MODE 加密
			int blockSize = cipher.getBlockSize();
			int outputSize = cipher.getOutputSize(data.length);
			int leavedSize = data.length % blockSize;
			int blocksSize = leavedSize != 0 ? data.length / blockSize + 1
					: data.length / blockSize;
			byte[] raw = new byte[outputSize * blocksSize];
			int i = 0;
			while (data.length - i * blockSize > 0) {
				if (data.length - i * blockSize > blockSize) {
					cipher.doFinal(data, i * blockSize, blockSize, raw, i
							* outputSize);
				} else {
					cipher.doFinal(data, i * blockSize, data.length - i
							* blockSize, raw, i * outputSize);
				}
				i++;
			}
			return raw;
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 根据privateKey 对data进行解密.
	 * 
	 * @param privateKey
	 * @param data
	 * @throws Exception
	 * @author Peter.Qiu
	 */
	public static byte[] decryptMode(PrivateKey privateKey, byte[] data)
			throws Exception {
		Cipher cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
		cipher.init(Cipher.DECRYPT_MODE, privateKey);// DECRYPT_MODE 解密
		int blockSize = cipher.getBlockSize();
		ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
		int j = 0;

		while (data.length - j * blockSize > 0) {
			bout.write(cipher.doFinal(data, j * blockSize, blockSize));
			j++;
		}
		return bout.toByteArray();
	}

	/**
	 * 获取密钥.
	 * 
	 * @param rsaKeyStore
	 * @return
	 * @throws Exception
	 * @author Peter.Qiu
	 */
	public static KeyPair getKeyPair(String rsaKeyStore) throws Exception {
		FileInputStream fis = new FileInputStream(rsaKeyStore);
		ObjectInputStream oos = new ObjectInputStream(fis);
		KeyPair kp = (KeyPair) oos.readObject();
		oos.close();
		fis.close();
		return kp;
	}

	/**
	 * 将密钥写入文件.
	 * 
	 * @param kp
	 * @param path
	 * @throws Exception
	 * @author Peter.Qiu
	 */
	public static void saveKeyPair(KeyPair kp, String path) throws Exception {
		File file = new File(path);
		if (!file.exists() || file.isDirectory()) {
			file.createNewFile();
		}
		FileOutputStream fos = new FileOutputStream(path);
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		// 生成密钥
		oos.writeObject(kp);
		oos.close();
		fos.close();
	}

	/**
	 * 用于生成公匙或私匙.
	 * 
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @author Peter.Qiu
	 */
	public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {

		SecureRandom sr = new SecureRandom();
		KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA",
				new BouncyCastleProvider());
		// 注意密钥大小最好为1024,否则解密会有乱码情况.
		kg.initialize(1024, sr);
		KeyPair genKeyPair = kg.genKeyPair();
		return genKeyPair;

	}

	/**
	 * 将公密或私密写入文件.
	 * 
	 * @param obj
	 * @param path
	 * @throws Exception
	 * @author Peter.Qiu
	 */
	public static void saveFile(Object obj, String path) throws Exception {
		File file = new File(path);
		if (!file.exists() || file.isDirectory()) {
			file.createNewFile();
		}
		FileOutputStream fos = new FileOutputStream(path);
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		// 生成密钥
		oos.writeObject(obj);
		oos.close();
		fos.close();
	}

	/**
	 * 获取公密.
	 * 
	 * @param publicKeyPath
	 * @return
	 * @throws Exception
	 * @author Peter.Qiu
	 */
	public static PublicKey getPublicKey(String publicKeyPath) throws Exception {
		FileInputStream fis = new FileInputStream(publicKeyPath);
		ObjectInputStream oos = new ObjectInputStream(fis);
		PublicKey kp = (PublicKey) oos.readObject();
		oos.close();
		fis.close();
		return kp;
	}

	/**
	 * 获取私密.
	 * 
	 * @param privateKeyPath
	 * @return
	 * @throws Exception
	 * @author Peter.Qiu
	 */
	public static PrivateKey getPrivateKey(String privateKeyPath)
			throws Exception {
		FileInputStream fis = new FileInputStream(privateKeyPath);
		ObjectInputStream oos = new ObjectInputStream(fis);
		PrivateKey kp = (PrivateKey) oos.readObject();
		oos.close();
		fis.close();
		return kp;
	}

	public static void main(String[] args) throws Exception {
		File dir = new File("./key/");
		if (!dir.exists()) {
			dir.mkdir();
		}
		// 获取公匙及私匙
		KeyPair generateKeyPair = getKeyPair("./key/key");

		// 生成公钥及私钥
		// generateKeyPair = generateKeyPair();

		// 存储KeyPair到本地用于后期解密 注意修改前台RSAKeyPair
		// saveKeyPair(generateKeyPair,"./key/key");

		System.out.println("generateKeyPair : " + generateKeyPair);
		// 公匙 用于前台加密
		PublicKey publicKey = null;// generateKeyPair.getPublic();
		publicKey = getPublicKey("./key/publicKey.key");
		System.out.println("publicKey:" + publicKey);
		// saveFile(publicKey,"./key/publicKey.key");
		// 私匙 存储在后台用于解密
		PrivateKey privateKey = null;// generateKeyPair.getPrivate(); //
		privateKey = getPrivateKey("./key/privateKey.key");//
		System.out.println("privateKey:" + privateKey);
		// saveFile(privateKey,"./key/privateKey.key");

		// 测试加密解密
		String test = "saaaa";
		test = "Peter.Qiu丘丘丘邱";
		System.out.println("加密前字符:" + test);
		byte[] en_test = encryptMode(publicKey, test.getBytes("UTF-8"));
		System.out.println("加密后字符:" + new String(en_test));

		byte[] de_test = decryptMode(privateKey, en_test);
		System.out.println("解密后字符:" + new String(de_test, "UTF-8"));

	}

}</span>


转摘请注明:http://blog.csdn.net/qiuzhping/article/details/44344373

效果图:

技术分享

对应完整的项目:http://download.csdn.net/detail/qiu_11/8509319


Java非对称加密算法--RSA加密算法

标签:非对称加密解密   security   java   rsa   

原文地址:http://blog.csdn.net/qiuzhping/article/details/44344373

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!