转自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. You Are the One HDU - 4283 (区间DP)

    Problem Description The TV shows such as You Are the One has been very popular. In order to meet the ...

  2. C# http 性能优化500毫秒到 60 毫秒

    偶然发现 C# 的 HttpRequest 要比 Chrome 请求同一Url 慢好多.C# HttpRequest 要500毫秒 而Chrome 只需要 39ms. 作为有责任感的 码农.这个 必须 ...

  3. MySQL 主从复制实战解析

    前言:前面几篇文章讲解了在应用层读写分离的配置和使用,这篇文章将来个主从复制的实战解析. 说明:主从复制,读写分离结构图 原理图 主库生成一个线程: Binlog Dump线程 1.此线程运行在主库, ...

  4. 基于Redis的分布式锁真的安全吗?

    说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...

  5. 使用VLC Activex插件做网页版视频播放器

    网上找的一个小例子,包括时长播放时间等等都有. mrl可以设置本地文件,这样发布网站后只能播放本地有的文件, 如果视频文件全在服务器上,其他电脑想看的话,则可以IIS上发布个视频文件服务器,类似htt ...

  6. [JSOI2010]满汉全席 2-SAT

    https://www.luogu.org/problemnew/show/P4171 意识到图中只有两种不同的菜系:满和汉 并且检查员类似于一个约束,可以发现这就是一个2-sat模型,满和汉分别对应 ...

  7. 001 UI介绍

    UI全称:User Interface,即用户界面 UI的职责:负责人机之间的交互,它需要将关键信息,操作逻辑等展示给用户 UI在游戏中承担的职责: 1.游戏美术风格的重要组成部分 2.承担着重要的美 ...

  8. 关于IsDeleted,Islock,State类型Bit,char(1),tinyint的探讨

    做IsDeleted,Islock,State时,字段的数据类型选择一般有三种Bit,char,tinyint,大于2个字节的类型我们暂时不考虑,这里以mssql为例. 数据大小​: Bit,char ...

  9. 第30月第18天 autolayout代码

    1.上下左右 [tipsLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; { id view1 = tipsLabel; id view2 ...

  10. istio环境搭建for macbook

    首先需要搭建docker+k8s环境,如何搭建这里就不再赘述,可以自行搜索. 打开命令行,运行命令: curl -L https://git.io/getLatestIstio | ISTIO_VER ...