转自https://www.cnblogs.com/Irving/p/9551110.html

OpenSSL 提取 pfx 数字证书公钥与私钥

 

由于之前生产环境已经使用了 Identityserver4 用来做授权与认证的服务,而新项目采用 Spring Cloud 微服务体系,一方面 Spring Cloud 官方暂时只支持 OAuth2.0 协议,还不支持 OpenID Connect 协议(由于考虑到前项目后端分离登陆安全相关的功能已经做好了,不考虑再次修改 Spring Security 二次开发与其他开源框架如:Keycloak);另外默认 Identityserver4  也支持 JwtToken ,现在的思路是登陆使用 Identityserver4  的 OpenID Connect 协议认证,授权是在 Zuul 网关中获得 Identityserver4 服务端的公钥从而进行验签,所以就有了这篇文章。

创建证书

#生成私钥文件
openssl genrsa -out idsrv4.key 2048
#创建证书签名请求文件 CSR(Certificate Signing Request),用于提交给证书颁发机构(即 Certification Authority (CA))即对证书签名,申请一个数字证书。
openssl req -new -key idsrv4.key -out idsrv4.csr
#生成自签名证书(证书颁发机构(CA)签名后的证书,因为自己做测试那么证书的申请机构和颁发机构都是自己,crt 证书包含持有人的信息,持有人的公钥,以及签署者的签名等信息。当用户安装了证书之后,便意味着信任了这份证书,同时拥有了其中的公钥。)
openssl x509 -req -days 365 -in idsrv4.csr -signkey idsrv4.key -out idsrv4.crt
#自签名证书与私匙合并成一个文件
openssl pkcs12 -export -in idsrv4.crt -inkey idsrv4.key -out idsrv4.pfx 或
openssl req -newkey rsa:2048 -nodes -keyout idsrv4.key -x509 -days 365 -out idsrv4.cer
openssl pkcs12 -export -in idsrv4.cer -inkey idsrv4.key -out idsrv4.pfx

OpenSSL 提取 pfx 证书公钥与私钥

从pfx证书中提取密钥信息,并转换为key格式(pfx使用pkcs12模式补足)
提取密钥对(如果pfx证书已加密,会提示输入密码)
openssl pkcs12 -in idsrv4.pfx -nocerts -nodes -out idsrv4.key
从密钥对提取公钥
openssl rsa -in idsrv4.key -pubout -out idsrv4_pub.key
从密钥对提取私钥
openssl rsa -in idsrv4.key -out idsrv4_pri.key
因为RSA算法使用的是 pkcs8 模式补足,需要对提取的私钥进一步处理得到最终私钥
openssl pkcs8 -topk8 -inform PEM -in idsrv4_pri.key -outform PEM -nocrypt

代码方式获取

public class PFXUtil {

    /**
* 获取RSA算法的keyFactory
*
* @return
*/
private static KeyFactory getKeyFactory() throws Exception {
return getKeyFactory("RSA");
} /**
* 获取指定算法的keyFactory
*
* @param algorithm
* @return
*/
private static KeyFactory getKeyFactory(String algorithm) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
return keyFactory;
} /**
* 根据pfx证书获取keyStore
*
* @param pfxData
* @param password
* @return
* @throws Exception
*/
private static KeyStore getKeyStore(byte[] pfxData, String password) throws Exception {
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new ByteArrayInputStream(pfxData), password.toCharArray());
return keystore;
} /**
* 根据pfx证书得到私钥
*
* @param pfxData
* @param password
* @throws Exception
*/
public static PrivateKey getPrivateKeyByPfx(byte[] pfxData, String password) throws Exception {
PrivateKey privateKey = null;
KeyStore keystore = getKeyStore(pfxData, password);
Enumeration<String> enums = keystore.aliases();
String keyAlias = "";
while (enums.hasMoreElements()) {
keyAlias = enums.nextElement();
if (keystore.isKeyEntry(keyAlias)) {
privateKey = (PrivateKey) keystore.getKey(keyAlias, password.toCharArray());
}
}
return privateKey;
} /**
* 根据pfx证书得到私钥
*
* @param pfxPath
* @param password
* @return
* @throws Exception
*/
public static PrivateKey getPrivateKeyByPfx(String pfxPath, String password) throws Exception {
File pfxFile = new File(pfxPath);
return getPrivateKeyByPfx(FileUtils.readFileToByteArray(pfxFile), password);
} /**
* 根据私钥字节数组获取私钥对象
*
* @param privateKeyByte
* @return
* @throws Exception
*/
public static PrivateKey getPrivateKey(byte[] privateKeyByte) throws Exception {
PrivateKey privateKey = null;
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyByte);
KeyFactory keyFactory = getKeyFactory();
privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
} /**
* 根据私钥Base64字符串获取私钥对象
*
* @param privateKeyStr
* @return
* @throws Exception
*/
public static PrivateKey getPrivateKey(String privateKeyStr) throws Exception {
byte[] privateKeyByte = Base64.decodeBase64(privateKeyStr);
return getPrivateKey(privateKeyByte);
} /**
* 根据公钥字节数组获取公钥
*
* @param publicKeyByte 公钥字节数组
* @return
* @throws Exception
*/
public static PublicKey getPublicKey(byte[] publicKeyByte) throws Exception {
PublicKey publicKey = null;
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyByte);
KeyFactory keyFactory = getKeyFactory();
publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
} /**
* 根据公钥base64字符串获取公钥
*
* @param publicKeyStr Base64编码后的公钥字节数组
* @return
* @throws Exception
*/
public static PublicKey getPublicKey(String publicKeyStr) throws Exception {
byte[] publicKeyByte = Base64.decodeBase64(publicKeyStr);
return getPublicKey(publicKeyByte);
} /**
* 根据pfx证书获取证书对象
*
* @param pfxData pfx的字节数组
* @param password pfx证书密码
* @return
* @throws Exception
*/
public static X509Certificate getX509Certificate(byte[] pfxData, String password) throws Exception {
X509Certificate x509Certificate = null;
KeyStore keystore = getKeyStore(pfxData, password);
Enumeration<String> enums = keystore.aliases();
String keyAlias = "";
while (enums.hasMoreElements()) {
keyAlias = enums.nextElement();
if (keystore.isKeyEntry(keyAlias)) {
x509Certificate = (X509Certificate) keystore.getCertificate(keyAlias);
}
}
return x509Certificate;
} /**
* 根据pfx证书获取证书对象
*
* @param pfxPath pfx证书路径
* @param password pfx证书密码
* @return
* @throws Exception
*/
public static X509Certificate getX509Certificate(String pfxPath, String password) throws Exception {
File pfxFile = new File(pfxPath);
return getX509Certificate(FileUtils.readFileToByteArray(pfxFile), password);
} //生成pkcs12 /**
* 根据私钥、公钥证书、密码生成pkcs12
*
* @param privateKey 私钥
* @param x509Certificate 公钥证书
* @param password 需要设置的密钥
* @return
* @throws Exception
*/
public static byte[] generatorPkcx12(PrivateKey privateKey, X509Certificate x509Certificate, String password)
throws Exception {
Certificate[] chain = {x509Certificate};
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(null, password.toCharArray());
keystore.setKeyEntry(x509Certificate.getSerialNumber().toString(), privateKey, password.toCharArray(), chain);
ByteArrayOutputStream bytesos = new ByteArrayOutputStream();
keystore.store(bytesos, password.toCharArray());
byte[] bytes = bytesos.toByteArray();
return bytes;
} //合成pfx /**
* 根据私钥、公钥证书、密钥,保存为pfx文件
*
* @param privateKey 私钥
* @param x509Certificate 公钥证书
* @param password 打开pfx的密钥
* @param saveFile 保存的文件
* @return
* @throws Exception
*/
public static String generatorPFX(PrivateKey privateKey, X509Certificate x509Certificate, String password, File
saveFile) throws Exception {
//判断文件是否存在
if (!saveFile.exists()) {
//判断文件的目录是否存在
if (!saveFile.getParentFile().exists()) {
saveFile.getParentFile().mkdirs();
}
saveFile.createNewFile();
}
byte[] pkcs12Byte = generatorPkcx12(privateKey, x509Certificate, password);
FileUtils.writeByteArrayToFile(saveFile, pkcs12Byte);
return saveFile.getPath();
}
} public class TestRsa { @Test
public void contextLoads() {
String pfxPath ="D:\\github\\SecuringForWebAPI\\IdSrv4.HostSrv\\Certs\\idsrv4.pfx";
String password = "123456";
try {
//私钥:pfx文件中获取私钥对象
PrivateKey privateKey = getPrivateKeyByPfx(pfxPath, password);
byte[] privateKeyByte = privateKey.getEncoded();
String privateKeyStr = Base64.encodeBase64String(privateKeyByte);
System.out.println("私钥Base64字符串:" + privateKeyStr);
//=====私钥Base64字符串转私钥对象
PrivateKey privateKey2 = getPrivateKey(privateKeyStr);
System.out.println("私钥Base64字符串2:" + Base64.encodeBase64String(privateKey2.getEncoded()));
//证书:从pfx文件中获取证书对象
X509Certificate certificate = getX509Certificate(pfxPath, password);
System.out.println("证书主题:" + certificate.getSubjectDN().getName());
String publicKeyStr = Base64.encodeBase64String(certificate.getPublicKey().getEncoded());
System.out.println("公钥Base64字符串:" + publicKeyStr);
//=====根据公钥Base64字符串获取公钥对象
System.out.println("公钥Base64字符串2:" + Base64.encodeBase64String(getPublicKey(publicKeyStr).getEncoded()));
// //PFX:合成pfx(需要私钥、公钥证书)
// String savePath = generatorPFX(privateKey, certificate, "1", new File
// ("C:\\Users\\irving\\Desktop\\idrv4.pfx"));
// System.out.println(savePath);
} catch (Exception e) {
e.printStackTrace();
}
}
}

REFER:
OpenSSL使用文档
https://github.com/KaiZhang890/openssl-howto

【转载】OpenSSL 提取 pfx 数字证书公钥与私钥的更多相关文章

  1. OpenSSL 提取 pfx 数字证书公钥与私钥

    由于之前生产环境已经使用了 Identityserver4 用来做授权与认证的服务,而新项目采用 Spring Cloud 微服务体系,一方面 Spring Cloud 官方暂时只支持 OAuth2. ...

  2. openssl提取pfx证书密钥对

    刚做银联的项目,对方给了1.pfx和1.cer两个测试文件,总结一下利用这两个文件提取出文本 银联提供两个测试证书  1.pfx 和 1.cer . 其中 pfx证书包含RSA的公钥和密钥;cer证书 ...

  3. .NET Core加解密实战系列之——使用BouncyCastle制作p12(.pfx)数字证书

    简介 加解密现状,编写此系列文章的背景: 需要考虑系统环境兼容性问题(Linux.Windows) 语言互通问题(如C#.Java等)(加解密本质上没有语言之分,所以原则上不存在互通性问题) 网上资料 ...

  4. xamarin uwp数字证书公钥私钥

    对于数字证书存储导入到电脑中,采用如下方式: /// <summary> /// 导入证书 /// </summary> /// <param name="ra ...

  5. OpenSSL 与 SSL 数字证书概念贴

    SSL/TLS 介绍见文章 SSL/TLS原理详解(http://seanlook.com/2015/01/07/tls-ssl). 如果你想快速自建CA然后签发数字证书,请移步 基于OpenSSL自 ...

  6. 提取pfx证书公钥和私钥

    从pfx提取密钥信息,并转换为key格式(pfx使用pkcs12模式补足) 1.提取密钥对(如果pfx证书已加密,会提示输入密码.) openssl pkcs12 -in 1.pfx -nocerts ...

  7. 创建pfx数字证书

    相关参考: 安全工具: http://msdn.microsoft.com/zh-cn/library/dd233106(v=vs.110).aspx makecert: http://msdn.mi ...

  8. iOS 申请distribution证书, 公钥,私钥

    私钥只有在本机生成CSR文件的时候会产生,公钥会在CSR文件传给apple时,apple产生.

  9. [转载] 创建为ClickOnce清单签名的.pfx格式数字证书

    使用vs2013自动创建的.pfx数字证书默认有效期只有一年,并且“颁发者”.“颁发给”均为当前机器名和当前登陆用户名的组合,其实我们完全可以创建更友好的.pfx数字证书. 打开Microsoft . ...

随机推荐

  1. Codeforces 1108F MST Unification(最小生成树性质)

    题目链接:MST Unification 题意:给定一张连通的无向带权图.存在给边权加一的操作,求最少操作数,使得最小生成树唯一. 题解:最小生成树在算法导论中有这个性质: 把一个连通无向图的生成树边 ...

  2. 码云报错:fatal: remote origin already exists.解决方法

    今天在提交Git的时候,遇到了几个问题,记录一下,方便以后查找O(∩_∩)O 第一个问题 git remote add origin************** fatal: remote origi ...

  3. eclipse 包 取消代码第一行package包名 自动补全时取消自动引入包名 修改名字 取消引用 自动导入publilc static void main(String[] args) {}

    --项目 --包 包是为了管理类文件,同个包下不允许同名类文件,但不同包就可以,把类放在包里是规范 (https://zhidao.baidu.com/question/239471930532952 ...

  4. android studio 报红解决

    /Users/houzhibin/gradle/wrapper/dists/gradle-4.1-all/bzyivzo6n839fup2jbap0tjew/gradle-4.1-all.zip

  5. JS学习笔记Day25

    一.VSN 和 GitHub (一)VSN集中化的版本控制系统: 拥有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新. (二 ...

  6. (九) 主机增加打印(串口+ssh)

    目录 主机增加打印(串口+ssh) ssh 串口打印 title: 主机增加打印(串口+ssh) date: 2019/4/23 20:10:00 toc: true --- 主机增加打印(串口+ss ...

  7. uboot2012(一)分析重定位

    目录 引入 环境配置 编译体验 入口查找 代码分析 board_init_f pie 内存分布分析 SP设置 board_init_f 重定位 代码段重定位实现 变量地址修改 参考 title: ub ...

  8. Redis 使用介绍-Linux-Bash

    1.进入Bash redis-cli 2.查看所有的key keys * 1.Key-Value 1.1.查看key-value值 1.2.修改key值 2.List 1> string lis ...

  9. 五十五、linux 编程——TCP 连接和关闭过程及服务器的并发处理

    55.1 TCP 连接和关闭过程 55.1.1 介绍 建立连接的过程就是三次握手的过程:客户端发送 SYN 报文给服务器,服务器回复 SYN+ACK 报文,客户机再发送 ACK 报文. 关闭连接的过程 ...

  10. 如何在Eclipse中创建web项目并使用tomcat8 运行servlet开发简单的动态网页?

    今天花了一天时间.因为用eclipse没多久,不是很熟悉使用,看的教程又是使用myeclipse的,但是eclipse相对没有myeclipse灵活,所以在网上找了很多资料,最后算是可以实现了.新手可 ...