rsa加密 工具类

3)  RSA

RSA 是一种非对称加解密算法。

RSA is named from the initials of the authors, Ron Rivest, Adi Shamir, and

Leonard Adleman,who first published the algorithm.  

RSA 与 DSA 都是非对称加密算法。其中RSA的安全性是基于极其困难的大整数的分解(两个素数的乘积);DSA 的安全性

是基于整数有限域离散对数难题。基本上可以认为相同密钥长度的 RSA 算法与 DSA 算法安全性相当。

公钥用于加密,它是向所有人公开的;私钥用于解密,只有密文的接收者持有。

适用OPENSSL 适用RSA 的命令如下:

生成一个密钥(私钥)

[root@hunterfu ~]# openssl genrsa -out private.key 1024

注意: 需要注意的是这个文件包含了公钥和密钥两部分,也就是说这个文件即可用来加密也可以用来解密,后面的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



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.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;

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 = "**"; //密钥信息用 BASE64 编码加密过,需要先解密
		String key4096 = "**";
		initRSAKEY(key4096);
		//		String privateKeyPath="";
		//		initRSAKEY(new File(privateKeyPath));
	}

	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();
			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);
			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();
		}

	}

	/**
	 * @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 < 10; 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));
	}

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值