关于RSA非对称加密的一点心得

   最近的一个项目中,要用到加密的知识。于是上网查了一些资料,翻看了一本很久以前买的书《JAVA加密与解密的艺术》,然后自己琢磨了一下,最后决定用了RSA典型非对称加密算法。下面就自己研究的代码分享一下。
    

package com.security.rsa;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

/**
 * RSA安全编码组件
 * @author Administrator
 *
 */
public abstract class RSACoder {

	//非对称加密密钥算法
	public static final String KEY_ALGORITHM="RSA";
	//公钥
	private static final String PUBLIC_KEY="RSAPublicKey";
	//私钥
	private static final String PRIVATE_KEY="RSAPrivateKey";
	
	
	private static FileOutputStream public_file_out = null;
	private static ObjectOutputStream public_object_out = null;
	private static FileOutputStream private_file_out = null;
	private static ObjectOutputStream private_object_out = null;
	/**
	 * RSA密钥长度
	 * 默认1024位
	 * 密钥长度必须是64的倍数
	 * 范围在512-65536
	 */
	
	private static final int KEY_SIZE=512;
	
	/**
	 * 私钥解密
	 * @param data 待解密数据
	 * @param key 私钥
	 * @param byte[] 解密数据
	 * @throws Exception
	 * 
	 */
	public static byte[] decryptByPrivateKey(byte[] data,byte[] key) throws Exception {
		//取得私钥
		PKCS8EncodedKeySpec pkcs8keyspec = new PKCS8EncodedKeySpec(key);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		//生成私钥
		PrivateKey privatekey =keyFactory.generatePrivate(pkcs8keyspec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, privatekey);
		
		return cipher.doFinal(data);
	}
	
	/**
	 * 公钥解密
	 * @param data 待解密数据
	 * @param key 公钥
	 * @param byte[] 解密数据
	 * @throws Exception
	 */
	public static byte[] decryptByPublicKey(byte[] data,byte[] key) throws Exception{
		
		//取得公钥
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		//生成公钥
		PublicKey publickey = keyFactory.generatePublic(x509KeySpec);
		//对数据解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, publickey);
		
		return cipher.doFinal(data);
	}
	
	/**
	 * 公钥加密
	 */
	public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception{
		//取得公钥
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		PublicKey publickey = keyFactory.generatePublic(x509KeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, publickey);
		return cipher.doFinal(data);
	}
	
	
	
	/**
	 * 私钥加密
	 */
	public static byte[] encryptByPrivateKey(byte[] data,byte[] key) throws Exception{
		PKCS8EncodedKeySpec  pkcs8KeySpec =new PKCS8EncodedKeySpec(key);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
		//对数据加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, privateKey);
		
		return cipher.doFinal(data);
	}
	
	/**
	 *取得私钥
	 */
	public static byte[] getPrivateKey(Map keyMap) throws Exception{
		Key key =(Key) keyMap.get(PRIVATE_KEY);
		return key.getEncoded();
	}
	/**
	 * 取得公钥
	 */
	
	public static byte[] getPublicKey(Map keyMap) throws Exception{
		Key key =(Key) keyMap.get(PUBLIC_KEY);
		return key.getEncoded();
	}
	
	/**
	 * 初始化密钥
	 */
	public static Map initKey() throws Exception{
		
		//实例化密钥对生成器
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
		//初始化密钥对生成器
		keyPairGen.initialize(KEY_SIZE);
		//生成密钥对
		KeyPair  keyPair = keyPairGen.generateKeyPair();
		//公钥
		RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
		//私钥
		RSAPrivateKey privateKey =(RSAPrivateKey) keyPair.getPrivate();
		//封装密钥
		Map keyMap = new HashMap(2);
		
		keyMap.put(PUBLIC_KEY, publicKey);
		keyMap.put(PRIVATE_KEY, privateKey);
		
		
//		//将公钥放到D盘根目录下
//		public_file_out = new FileOutputStream("d:/" + "/public_key.cer");
//		public_object_out = new ObjectOutputStream(public_file_out);
//		public_object_out.writeObject(publicKey);
//		saveKey(publicKey, "publicKey.cer");
//		
//		
//		//将私钥放到D盘根目录下
//		private_file_out = new FileOutputStream("d:/" + "/private_key.key");
//		private_object_out = new ObjectOutputStream(private_file_out);
//		private_object_out.writeObject(publicKey);
		
		
		saveKey(publicKey, "public_key.cer");
		saveKey(privateKey, "private_key.key");
		
		return keyMap;
	}
	
	
	/**
	 * 保存密钥的方法
	 * @param key
	 * @param keyName
	 * @throws Exception
	 */
	public static void saveKey(Key key,String keyName) throws Exception{
		FileOutputStream foskey=new FileOutputStream(keyName);
		ObjectOutputStream oos=new ObjectOutputStream(foskey);
		oos.writeObject(key);
		oos.close();
		foskey.close();
	}
	
	
}

 RSACoder 是基础类。下面是测试类,不过测试类写的比较简单。 

package com.security.rsa.test;

import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.junit.Before;
import org.junit.Test;

import com.security.rsa.RSACoder;

/**
 * RSA校验
 * @author Administrator
 *
 */
public class RSACoderTest {

	//公钥
	private byte[] privateKey;
	//私钥
	private byte[] publicKey;
	
	
	/**
	 * 初始化密钥
	 */
	@Before
	public void initKey() throws Exception{
		Map keyMap = RSACoder.initKey();
		
		publicKey = RSACoder.getPublicKey(keyMap);
		privateKey = RSACoder.getPrivateKey(keyMap);
		
		System.err.println("公钥:\n"+Base64.encodeBase64String(publicKey));
		System.err.println("私钥:\n"+Base64.encodeBase64String(privateKey));
		
	}
	
	
	
	/**
	 * 校验
	 * 
	 */
	@Test
	public void test() throws Exception{
		
		
		System.err.println("\n-----私钥加密-----公钥解密");
		String inputStr1 = "RSA算法加密";
		byte[] data1 = inputStr1.getBytes();
		System.err.println("原文:\n"+inputStr1);
		//加密
		byte[] encodeData1 = RSACoder.encryptByPrivateKey(data1, privateKey);
		System.err.println("加密后:\n"+Base64.encodeBase64String(encodeData1));
		//解密
		byte[] decodeData1 = RSACoder.decryptByPublicKey(encodeData1, publicKey);
		String outputStr1 = new String(decodeData1);
		System.err.println("解密后:\n"+outputStr1);
	}
}

   写这篇文章记录一下最近的历程。当然加密解密的路远不止这么简单,希望自己接下来能多学习,多成长,共勉!

你可能感兴趣的:(关于RSA非对称加密的一点心得)