总结:从KeyStore中提取公私钥并实现RSA加密算法

 

在构建Java代码实现前,我们要先完成keystore文件的构建。

1.    生成keystore文件

在命令行下执行以下命令:

Keytool –genkey -alias my_alias  -keyalg RSA  –keystore  C:\mykeystore.keystore  -validity 1830  -keysize 1024  -storepass  123456 -keypass pass -dname "CN=Jack,OU=腾讯,O=腾讯,L=深圳市,ST=广东省,C=Tecent"

 

命令说明:

(1)     -genkey    表示要创建新的密钥

 

(2)     -alias   别名,每个keystore都关联这一个独一无二的alias,这个alias通常不区分大小写。

 

(3)     -keystore    keystore文件的存储位置,文件扩展名为".keystore"。

 

(4)     -keyalg       指定密钥的算法 (如 RSA  DSA(如果不指定默认采用DSA))。

 

(5)     -validity     指定有效期(天),默认90天。

 

(6)     -keysize      指定密钥长度。

 

(7)     -storepass   指定密钥库的访问密码(获取keystore信息所需的密码)

 

(8)     -keypass      指定别名条目的密码(私钥的密码)

 

(9)     -dname       指定证书拥有者信息 例如:  "CN=名字与姓氏,OU=组织单位名称,O=组织名称,L=城市或区域名称,ST=州或省份名称,C=单位的两字母国家代码"。

 

OK,准备工作完成,开始Java实现!

 

2.  实现Java从keystore文件中提取公、私钥

由于无法通过KEYTOOL工具来提取私钥的..我们只能通过Java的KeyStore类getEntry() 或者getKey()来提取私钥,偶用的是getKey()方法的^_^…….

下面开始上代码:

 

由于从keystore文件中获取的公私钥均是字节码,不便于显示、传输,因此先上一个基础Coder类,实现Base64转码功能.

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
 * 基础加密组件
 * 
 * @author 奔跑的蜗牛
 * @version 1.0
 * @since 1.0
 */
public abstract class Coder {

	/**
	 * BASE64解密
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] decryptBASE64(String key) throws Exception {
		return (new BASE64Decoder()).decodeBuffer(key);
	}

	/**
	 * BASE64加密
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encryptBASE64(byte[] key) throws Exception {
		return (new BASE64Encoder()).encodeBuffer(key).replace("\r", "").replace("\n", "");
	}
}

 

下面的KeyStoreCoder类实获取公、私钥,以及实现RSA加密算法的公钥加密、私钥解密功能:

import java.io.FileInputStream;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import com.techshino.base.Coder;

public class KeyStoreCoder extends Coder {

	/**
	 * Java密钥库(Java Key Store,JKS)KEY_STORE
	 */
	public static final String KEY_STORE = "JKS";

	public static final String X509 = "X.509";

	/**
	 * 获得KeyStore
	 * 
	 * @author    奔跑的蜗牛
	 * @version   2012-3-16
	 * @param keyStorePath
	 * @param password
	 * @return
	 * @throws Exception
	 */
	private static KeyStore getKeyStore(String keyStorePath, String password)
			throws Exception {
		
		FileInputStream is = new FileInputStream(keyStorePath);
		KeyStore ks = KeyStore.getInstance(KEY_STORE);
		ks.load(is, password.toCharArray());
		is.close();
		return ks;
	}

	/**
	 * 由KeyStore获得私钥
	 * @author    奔跑的蜗牛
	 * @param keyStorePath
	 * @param alias
	 * @param storePass
	 * @return
	 * @throws Exception
	 */
	private static PrivateKey getPrivateKey(String keyStorePath, String alias, String storePass, String keyPass) throws Exception {
		KeyStore ks = getKeyStore(keyStorePath, storePass);
		PrivateKey key = (PrivateKey) ks.getKey(alias, keyPass.toCharArray());
		return key;
	}
	
	/**
	 * 由Certificate获得公钥
	 * @author    奔跑的蜗牛
	 * @param keyStorePath
	 *            KeyStore路径
	 * @param alias
	 *            别名
	 * @param storePass
	 *            KeyStore访问密码
	 * @return
	 * @throws Exception
	 */
	private static PublicKey getPublicKey(String keyStorePath, String alias, String storePass) throws Exception {
		KeyStore ks = getKeyStore(keyStorePath, storePass);
		PublicKey key = ks.getCertificate(alias).getPublicKey();
		return key;
	}
	   
	   /**
	    * 从KeyStore中获取公钥,并经BASE64编码
              * @author    奔跑的蜗牛
	     * @param keyStorePath
	    * @param alias
	    * @param storePass
	    * @return
	    * @throws Exception
	    */
	   public static String getStrPublicKey(String keyStorePath, String alias,String storePass) throws Exception{
		   PublicKey key = getPublicKey(keyStorePath, alias, storePass);
		   String strKey = Coder.encryptBASE64(key.getEncoded());		   
		   return strKey;
	   }
	   
	   /**
	    * 获取经BASE64编码后的私钥
        * @author    奔跑的蜗牛
	    * @param keyStorePath
	    * @param alias
	    * @param storePass
	    * @param keyPass
	    * @return
	    * @throws Exception
	    */
	   public static String getStrPrivateKey(String keyStorePath, String alias,String storePass, String keyPass) throws Exception{

		   PrivateKey key = getPrivateKey(keyStorePath, alias, storePass, keyPass);
		   String strKey = Coder.encryptBASE64(key.getEncoded());
		   return strKey;
	   }
	
	/**
	 * 使用公钥加密数据
          * @author    奔跑的蜗牛
	 * @param publicKey
	 * @param srcData
	 * @return
	 * @throws Exception
	 */
	public static String encryptByPublicKey(String publicKey, String srcData) throws Exception{
		//解密
		byte[] pk = Coder.decryptBASE64(publicKey);
		X509EncodedKeySpec spec = new X509EncodedKeySpec(pk);
		KeyFactory kf = KeyFactory.getInstance("RSA");
		//获取公钥
		PublicKey pubKey = kf.generatePublic(spec);
		
		// 对数据加密
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
		
		byte[] doFinal = cipher.doFinal(srcData.getBytes());
		return encryptBASE64(doFinal);
	}
	
	
	/**
	 * 使用私钥解密数据
          * @author    奔跑的蜗牛
	 * @param privateKey
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static String descryptByPrivateKey(String privateKey, String data) throws Exception{
		// BASE64转码解密私钥
		byte[] pk = Coder.decryptBASE64(privateKey);
		// BASE64转码解密密文
		byte[] text = decryptBASE64(data);
		PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(pk);
		KeyFactory kf = KeyFactory.getInstance("RSA");
		// 获取私钥
		PrivateKey prvKey = kf.generatePrivate(spec);
		
		// 对数据加密
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, prvKey);
		
		byte[] doFinal = cipher.doFinal(text);
		return new String(doFinal);
	}
}

 

再给出一个测试类,看看加解密效果:

package com.techshino;

import com.techshino.keystore.KeyStoreCoder;

public class TestDemo {

	public static void main(String[] args) {
		// 公钥
		String strPublicKey = "";
		// 私钥
		String strPrivateKey = "";
		
		try {
			strPublicKey = KeyStoreCoder.getStrPublicKey("F:\\GF.keystore", "myalias", "123456");
			System.out.println("公钥 = 【" + strPublicKey + "】");
			
			strPrivateKey = KeyStoreCoder.getStrPrivateKey("F:\\GF.keystore", "myalias", "123456", "pass");
			System.out.println("\n私钥 = 【" + strPrivateKey + "】");
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		
		// 原文
		String originalText = "Java实现RSA加密算法!";
		
		try {
			// RSA算法 公钥加密随机数
			String secretText = KeyStoreCoder.encryptByPublicKey(strPublicKey, originalText);
			System.out.println("\n经RSA公钥加密后 = " + secretText);
			System.out.println("\n经RSA公钥加密后长度 = " + secretText.length());
			
			String text = KeyStoreCoder.descryptByPrivateKey(strPrivateKey, secretText);
			System.out.println("\n经RSA私钥解密后 = 【" + text + "】");
			System.out.println("\n经RSA私钥解密后长度 = 【" + text.length() + "】");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}


控制台输出:

公钥 = 【MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5hLd9FryBcXdlKKGICd3/axQ85V5QmB/0P7a5KhZr0vJaGX+7YRJt4NYpH1+pEob0TkFaFXzYZSZIZa3R63tS1pWpvKSWdSEy1Spb9qBS1FMp0j8vhQN1ydFv1Fh3Ds6vqBoGYyvqmkRLworLDUiRWuEQqxNcsNjx2HMJnhpdxwIDAQAB】

私钥 = 【MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALmEt30WvIFxd2UooYgJ3f9rFDzlXlCYH/Q/trkqFmvS8loZf7thEm3g1ikfX6kShvROQVoVfNhlJkhlrdHre1LWlam8pJZ1ITLVKlv2oFLUUynSPy+FA3XJ0W/UWHcOzq+oGgZjK+qaREvCissNSJFa4RCrE1yw2PHYcwmeGl3HAgMBAAECgYEAgcFvzQ/v/OFtztUiVdIA8brlRspusxQTlXRSyyPC1tuOIrKfAmIcz7loUQ7ei5Sny4xIbUeGMJxesFhdwOthLxdcM54/lLW5ZCukUdUeLhjec1zTwCYZ9P1Ihrt63HOFRIVymak3f+eIWi4vmlNghSxyUGmXz1TYj/hI8wzWeZECQQDt7O5o+tZDGNPTzb4ppSyeZcRClcaLnvenig7Jyi3EOfv/gydANcUex5Fr8AnCkzAPIF0R3jU1vBbc0KKfnX1dAkEAx5yYjYQMJIFrJB6PYjhlwsOQi+cKFnphHnvaxPWP+LVAEduxjcKonvMmwqDq+6163omeXYEDn02pqeZoWMlxcwJAIpy7Oi5ziSNNfZyKs4hB63EmkgEz9w/TO15MNHLjIY7F6C/uP9sSqB2kPC2ZXeMHtMuifnzzBLQuJ0V6wvmoSQJBAKtfzLGi7vHgkuXdvuhq1yMR1+XlJAoMY5lSaI607ThwFGPApH265B4jT+HFWjldxaGNsYNBoqSAfuu5P1kLCfUCQQCJOv9FKXh5uWNO+Rcg4l7xwpnfCWtZKqrEWDy0cCfllfUPs0t8uRNZPKuroVGrZKJuvSGvQwM5g2pTAwRuctpM】

经RSA公钥加密后 = Ktj2HnI9MddXTcpYvORDrad9VmpMshBxMNro3QVXDw4meWadQXnEhc4s7w5sqPQezVCXEvDaONjngftXaYU5pagibaHh6jloIz562nqIDdYm91mbY1N8rgLH6S04zm4oqBhNai6xL5G/ecHvIySfCOqyItS1qWf7Umywhogluwc=

经RSA公钥加密后长度 = 172

经RSA私钥解密后 = 【Java实现RSA加密算法!】

经RSA私钥解密后长度 = 【14】


由此完成了Java实现RSA加解密功能(公钥加密、私钥解密),欢迎大家提出各种建议,大家互相学习~~~O(∩_∩)O~~~

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值