欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-22 16:18:18
...

   最近的一个项目中,要用到加密的知识。于是上网查了一些资料,翻看了一本很久以前买的书《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<String,Object> keyMap) throws Exception{
		Key key =(Key) keyMap.get(PRIVATE_KEY);
		return key.getEncoded();
	}
	/**
	 * 取得公钥
	 */
	
	public static byte[] getPublicKey(Map<String,Object> keyMap) throws Exception{
		Key key =(Key) keyMap.get(PUBLIC_KEY);
		return key.getEncoded();
	}
	
	/**
	 * 初始化密钥
	 */
	public static Map<String,Object> 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<String,Object> keyMap = new HashMap<String, Object>(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<String,Object> 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);
	}
}

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

相关标签: 加密解密