KeyStore加载PublicKey/PrivateKey(公/私钥)证书

开发过程中,对于签名和验签的问题,相信大家没少见过。很多时候,我们只是拿来就用,根本没留意里面的逻辑;

要么就是项目现有的签名和验签逻辑,要么就是拿demo里面的代码然后集成到项目中去,直接使用。

很少有自己去写一套签名和验签的代码逻辑,没有完全理解透彻之前,总觉得签名和验签神神秘秘高深的样子;

当你读透了里面的代码逻辑之后,发现整个相当简单,目前几个项目中都有签名和验签的公私钥证书,今天有空就把它分享一下:

1、PublicKey 公钥、PrivateKey 私钥、KeyStore 身份验证等名词解释和原理介绍

  • PublicKey 公钥

     顾名思义,是在签名和验签过程,验签所使用的公钥证书。公钥证书验签是不需要密码的,这里存在2个用户角色对象:A/B;

A和B分别有一套公私钥证书,那么站在A的角度上来说,想要使用证书实现A/B之间的安全协议通信:A持有的是A自己的私钥证书,和B的公钥证书;B持有的是B自己的私钥证书和A的公钥证书。通信中:A向B发送请求,那么A持有A自己的私钥进行签名,B持有A的公钥进行验签。相反同理

公私钥证书对比图
A持有配对B持有方式
A—PrivateKey<——>A—PublicKey签名/验签
B—PublicKey<——>B—PrivateKey验签/签名
    
  • PrivateKey 私钥

      同理,私钥证书就是用来签名的,私钥证书签名的时候一般都携带密码,和签名算法等;比如对称加密算法:AES,DES等,非对称加密算法:RSA、D-H等。具体看各自项目使用情况。

  • KeyStore

        Keystone(OpenStack Identity Service)是OpenStack框架中,负责身份验证、服务规则和服务令牌的功能, 它实现了OpenStack的IdentityAPI。Keystone类似一个服务总线, 或者说是整个Openstack框架的注册表, 其他服务通过keystone来注册其服务的Endpoint(服务访问的URL),任何服务之间相互的调用, 需要经过Keystone的身份验证, 来获得目标服务的Endpoint来找到目标服务。

        它是证书签名和验签过程,必须都要用到的一个身份验证的标识功能,好比公钥证书和私钥证书必须有一个裁判中间人来证明你们这对证书是合法且一致的。

代码如下:

package test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Enumeration;

import org.apache.commons.codec.binary.Base64;

//将私钥文件,公钥文件转换成PrivateKey,PublicKey对象或获取公私钥内容
//仅供参考,不提供性能,bug等问题保障

public class LoadCertUtil {
	public static PrivateKey getPriKey(KeyStore keyStore,String password){
		try {
			Enumeration<String> aliasenum  = keyStore.aliases();
			if (aliasenum.hasMoreElements()) {
				String keyAlias = aliasenum.nextElement();
				if (keyStore.isKeyEntry(keyAlias)) {
					PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias,password.toCharArray());
					return privateKey;
				}
			}
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (UnrecoverableKeyException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static PublicKey getPubKey(KeyStore keyStore){
		try {
			Enumeration<String> aliasenum = keyStore.aliases();
			String keyAlias = null;
			if (aliasenum.hasMoreElements()) {
				keyAlias = aliasenum.nextElement();
				if (keyStore.isKeyEntry(keyAlias)) {
					X509Certificate  x509Certificate = (X509Certificate) keyStore.getCertificate(keyAlias);
					PublicKey publicKey = x509Certificate.getPublicKey();
					return publicKey;
				}
			}
		  } catch (KeyStoreException e) {
			  e.printStackTrace();
		  }
		return null;
	}
	
	
	public static KeyStore loadKeyStore(String pfxkeyfile,String password){
		System.out.println("加载签名证书==>" + pfxkeyfile);
		FileInputStream fis = null;
		try {
			KeyStore keyStore = KeyStore.getInstance("PKCS12");
			fis = new FileInputStream(pfxkeyfile);
			char[] nPassword = password.toCharArray();
			if (null != keyStore) {
				keyStore.load(fis, nPassword);
			}
			return keyStore;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(null!=fis)
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
		return null;
	}
	
	public static PublicKey loadPubkey(String pubkeyfile){
		System.out.println("加载验签证书==>" + pubkeyfile);
		CertificateFactory cf = null;
		FileInputStream in = null;
		try {
			cf = CertificateFactory.getInstance("X.509");
			in = new FileInputStream(pubkeyfile);
			X509Certificate validateCert = (X509Certificate) cf.generateCertificate(in);
			return validateCert.getPublicKey();
		}catch (CertificateException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void main(String[] args) {
		String pfxkeyfile ="D:\\certs\\allcerts\\00010000new2048.pfx";
		String password = "000000";
		String pubkeyfile ="D:\\certs\\acp_test_verify_sign.cer";
		
		KeyStore keyStore = loadKeyStore(pfxkeyfile,password);
		PrivateKey privateKey = getPriKey(keyStore,password);
		System.out.println("签名私钥-私钥内容:" + Base64.encodeBase64String(privateKey.getEncoded()));
		PublicKey priPublicKey = getPubKey(keyStore);
		System.out.println("签名私钥-公钥内容:"+Base64.encodeBase64String(priPublicKey.getEncoded()));
		
		PublicKey publicKey = loadPubkey(pubkeyfile);
		System.out.println("公钥内容:"+Base64.encodeBase64String(publicKey.getEncoded()));
	}
}

 

同名原创公众号: 程序大视界

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序大视界

原创不易,请给点支持和鼓励吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值