针对pfx文件的解析及操作,java 标准库提供了很好的支持,需要做一定得封装,才能比较友好的使用,如下是我做的一些封装及核心代码,话不多说,直接上代码

本次JDK版本 zulu-11

pfx自定义封装类:方便使用公私钥信息

import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Date;@Data
@NoArgsConstructor
public class PfxObj implements Serializable {// 私钥private PrivateKey privateKey;// 公钥数组 private Certificate[] certificateChain;// 核心公钥信息,包含公钥、过期日期等等private X509Certificate x509Certificate;// 证书公钥过期时间private Date expiredAt;private String commonName;//aliasprivate String aliasName;
}

pfx解析及读写操作核心工具类


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.bindo.module.PfxObj;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;@Slf4j
public class PfxTools {public final static String UPDATE_PFX_KEY="manual_update_pfx";public final static String JUST_ONE_TASK="JUST_ONE_TASK";public final static Map<String,Date> MANUAL_UPDATE_PFX = new ConcurrentHashMap<>();/*** 读取pfx文件,获取KeyStore对象* @param keyStorePath pfx文件* @param password pfx访问密码* @return*/public static KeyStore loadKeyStore(String keyStorePath, String password) {KeyStore keyStore = null;FileInputStream fisFrom = null;try {keyStore = KeyStore.getInstance("PKCS12");fisFrom = new FileInputStream(keyStorePath);keyStore.load(fisFrom, password.toCharArray());} catch (Exception e) {log.error("加载pfx时异常,file" + keyStorePath, e);} finally {if (fisFrom != null) {try {fisFrom.close();} catch (IOException e) {log.error("关闭文件流异常.", e);}}}return keyStore;}/*** 保存KeyStore对象至pfx文件* @param ksFrom KeyStore对象* @param fromPw pfx访问密码* @param storePath pfx保存路径及文件* @return*/public static boolean storeKeyStore(KeyStore ksFrom, String fromPw, String storePath) {FileOutputStream fileOutputStream = null;try {fileOutputStream = new FileOutputStream(storePath);ksFrom.store(fileOutputStream, fromPw.toCharArray());} catch (Exception e) {log.error("保存pfx到文件异常.storePath=" + storePath, e);return false;} finally {if (fileOutputStream != null) {try {fileOutputStream.close();} catch (IOException e) {log.error("关闭文件流异常.", e);}}}return true;}/*** 读取pfx文件,生成pfx自定义对象(PfxObj)集合* @param pfxFileStr pfx文件* @param pfxPassword pfx访问密码* @return* @throws Exception*/public static Map<String, PfxObj> readPfxFile(String pfxFileStr, String pfxPassword) throws Exception {Map<String, PfxObj> pfxObjMap = new HashMap<>();KeyStore ks = KeyStore.getInstance("PKCS12");FileInputStream fis = new FileInputStream(pfxFileStr);// If the keystore password is empty(""), then we have to set// to null, otherwise it won't work!!!char[] nPassword = null;if ((pfxPassword == null) || pfxPassword.trim().equals("")) {nPassword = null;} else {nPassword = pfxPassword.toCharArray();}ks.load(fis, nPassword);fis.close();// System.out.println("keystore type=" + ks.getType());// Now we loop all the aliases, we need the alias to get keys.// It seems that this value is the "Friendly name" field in the// detals tab <-- Certificate window <-- view <-- Certificate// Button <-- Content tab <-- Internet Options <-- Tools menu// In MS IE 6.Enumeration enumas = ks.aliases();String keyAlias = null;PrivateKey prikey = null;int times = 0;while (enumas.hasMoreElements())// we are readin just one certificate.{keyAlias = (String) enumas.nextElement();prikey = (PrivateKey) ks.getKey(keyAlias, nPassword);Certificate cert = ks.getCertificate(keyAlias);X509Certificate x509Certificate = (X509Certificate) ks.getCertificate(keyAlias);Certificate[] certificateChain = ks.getCertificateChain(keyAlias);PublicKey pubkey = cert.getPublicKey();times++;PfxObj pfxObj = new PfxObj();pfxObj.setCertificateChain(certificateChain);pfxObj.setPrivateKey(prikey);pfxObj.setX509Certificate(x509Certificate);pfxObj.setAliasName(keyAlias);pfxObj.setCommonName(((JSONObject) JSON.toJSON(x509Certificate)).getJSONObject("subjectDN").getString("commonName"));pfxObj.setExpiredAt(x509Certificate.getNotAfter());pfxObjMap.put(keyAlias, pfxObj);}// System.out.println("=============== 证书数量=" + times + " =============");return pfxObjMap;}/*** 以account为维度,获取pfx证书,多个证书时,取最新的过期时间** @param pfxFileStr* @param pfxPassword* @return* @throws Exception*/public static Map<String, PfxObj> getPfxToSpAccountMap(String pfxFileStr, String pfxPassword) throws Exception {Map<String, PfxObj> pfxObjMap = readPfxFile(pfxFileStr, pfxPassword);Map<String, PfxObj> spAccountPfxMap = new HashMap<>();if (CollectionUtils.isEmpty(pfxObjMap)) {return spAccountPfxMap;}Iterator<Map.Entry<String, PfxObj>> iterator = pfxObjMap.entrySet().iterator();while (iterator.hasNext()) {Map.Entry<String, PfxObj> pfxCer = iterator.next();if (spAccountPfxMap.containsKey(pfxCer.getValue().getCommonName())) {if (spAccountPfxMap.get(pfxCer.getValue().getCommonName()).getExpiredAt().before(pfxCer.getValue().getExpiredAt())) {spAccountPfxMap.replace(pfxCer.getValue().getCommonName(), pfxCer.getValue());}} else {spAccountPfxMap.put(pfxCer.getValue().getCommonName(), pfxCer.getValue());}}return spAccountPfxMap;}/*** pfx的A文件写入至B文件* 此处未保存到文件,只是存入B的KeyStore对象* @param toFile 接收pfx的文件* @param toPw 接收文件的访问密码* @param fromFile 被复制的* @param fromPw* @return* @throws Exception*/public static KeyStore writePFX(String toFile, String toPw, String fromFile, String fromPw) throws Exception {KeyStore ksTo = KeyStore.getInstance("PKCS12");FileInputStream fisTo = new FileInputStream(toFile);ksTo.load(fisTo, toPw.toCharArray());KeyStore ksFrom = KeyStore.getInstance("PKCS12");FileInputStream fisFrom = new FileInputStream(fromFile);ksFrom.load(fisFrom, fromPw.toCharArray());Enumeration<String> aliases = ksFrom.aliases();while (aliases.hasMoreElements()) {String aliase = aliases.nextElement();if (!ksFrom.isKeyEntry(aliase)) {continue;}Key keyFrom = ksFrom.getKey(aliase, fromPw.toCharArray());Certificate[] certificateChainFrom = ksFrom.getCertificateChain(aliase);ksTo.setKeyEntry(aliase, keyFrom, toPw.toCharArray(), certificateChainFrom);}return ksTo;}/*** pfx的A文件写入至B文件* 只是写入到某个已存在的KeyStore对象,还未保存至文件* @param ksTo KeyStore接收公私钥* @param toPw 接收者的访问密码* @param fromFile 待读取的pfx文件* @param fromPw 访问密码* @return* @throws Exception*/public static KeyStore writePFX(KeyStore ksTo, String toPw, String fromFile, String fromPw) throws Exception {KeyStore ksFrom = KeyStore.getInstance("PKCS12");FileInputStream fisFrom = new FileInputStream(fromFile);ksFrom.load(fisFrom, fromPw.toCharArray());Enumeration<String> aliases = ksFrom.aliases();while (aliases.hasMoreElements()) {String aliase = aliases.nextElement();if (!ksFrom.isKeyEntry(aliase)) {continue;}Key keyFrom = ksFrom.getKey(aliase, fromPw.toCharArray());Certificate[] certificateChainFrom = ksFrom.getCertificateChain(aliase);ksTo.setKeyEntry(aliase, keyFrom, toPw.toCharArray(), certificateChainFrom);}return ksTo;}/*** pfx的A文件写入至B文件* 将pfx自定义对象写入到KeyStore,未保存至文件* @param ksTo KeyStore接收公私钥* @param toPw 接收者的访问密码* @param pfxObj pfx自定义对象* @return* @throws Exception*/public static KeyStore writePFX(KeyStore ksTo, String toPw, PfxObj pfxObj) throws Exception {ksTo.setKeyEntry(pfxObj.getCommonName(), pfxObj.getPrivateKey(), toPw.toCharArray(), pfxObj.getCertificateChain());return ksTo;}/*** 从pfx文件中删除某个alias的公私钥信息* 未保存至文件* @param fromFile* @param fromPw* @param aliaseRemove* @return* @throws Exception*/public static KeyStore removePFX(String fromFile, String fromPw, String aliaseRemove) throws Exception {KeyStore ksFrom = KeyStore.getInstance("PKCS12");FileInputStream fisFrom = new FileInputStream(fromFile);ksFrom.load(fisFrom, fromPw.toCharArray());Enumeration<String> aliases = ksFrom.aliases();boolean removeFlag = false;while (aliases.hasMoreElements()) {String aliase = aliases.nextElement();if (aliase.equalsIgnoreCase(aliaseRemove)) {removeFlag = true;}}if (removeFlag) {ksFrom.deleteEntry(aliaseRemove);}return ksFrom;}/*** 从KeyStore删除某个公私钥对* @param ksFrom* @param fromPw* @param aliaseRemove* @return* @throws Exception*/public static KeyStore removePFX(KeyStore ksFrom, String fromPw, String aliaseRemove) throws Exception {Enumeration<String> aliases = ksFrom.aliases();boolean removeFlag = false;while (aliases.hasMoreElements()) {String aliase = aliases.nextElement();if (aliase.equalsIgnoreCase(aliaseRemove)) {removeFlag = true;}}if (removeFlag) {ksFrom.deleteEntry(aliaseRemove);}return ksFrom;}/*** 下载pfx文件* @param fileUri* @param downloadedFile* @throws Exception*/public static void downloadNetFile(String fileUri, String downloadedFile) throws Exception {// 下载网络文件int bytesum = 0;int byteread = 0;URL url = new URL(fileUri);InputStream inStream = null;FileOutputStream fs = null;try {URLConnection conn = url.openConnection();inStream = conn.getInputStream();fs = new FileOutputStream(downloadedFile);byte[] buffer = new byte[1204];int length;while ((byteread = inStream.read(buffer)) != -1) {bytesum += byteread;fs.write(buffer, 0, byteread);}fs.flush();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {inStream.close();fs.close();}}/*** 执行shell命令* @param commands* @return*/public static List<String> executeNewFlow(List<String> commands) {List<String> rspList = new ArrayList<String>();Runtime run = Runtime.getRuntime();try {Process proc = run.exec("/bin/bash", null, null);BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);for (String line : commands) {out.println(line);}out.println("exit");// 这个命令必须执行,否则in流不结束。String rspLine = "";while ((rspLine = in.readLine()) != null) {System.out.println(rspLine);rspList.add(rspLine);}proc.waitFor();in.close();out.close();proc.destroy();} catch (IOException e1) {e1.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}return rspList;}/*** 是否在有效期内** @param expriedDate 过期时间* @param days        即将过期预警天数* @return*/public static boolean isValidIn(Date expriedDate, int days) {int expiredInTimes = days * 24 * 60 * 60 * 1000;long gapTime = expriedDate.getTime() - new Date().getTime();return gapTime - expiredInTimes > 0 ? true : false;}public static Integer extractSpId(String str) {if (StringUtils.isBlank(str) || !str.startsWith("SP") || !str.contains("-")) {log.error("无效的sp身份ID=" + str);return null;}int index = str.indexOf("-");Integer spId = null;try {spId = Integer.valueOf(str.substring(2, index));} catch (NumberFormatException e) {log.error("无效的sp身份ID=" + str, e);}return spId;}public static void main(String[] args) throws Exception {
//        Map<String, PfxObj> pfxObjMap = readPfxFile("/Users/bindo/Downloads/ecert.pfx", "123456");
//        Iterator<String> iterator = pfxObjMap.keySet().iterator();
//        Map<String,Integer> commonNameMap = new HashMap<>();
//        while (iterator.hasNext()){
//            String key = iterator.next();
//            String commonName = pfxObjMap.get(key).getCommonName();
//            if (commonNameMap.containsKey(commonName)){
//                commonNameMap.put(commonName,commonNameMap.get(commonName)+1);
//            }else {
//                commonNameMap.put(commonName,1);
//            }
//            // System.out.println("证书的alias="+key+", commonName="+commonName+", 有效期="+pfxObjMap.get(key).getX509Certificate().getNotAfter()+", 是否失效="+pfxObjMap.get(key).getX509Certificate().getNotAfter().before(new Date()));
//
//        }
//        Iterator<String> iterator1 = commonNameMap.keySet().iterator();
//        // System.out.println("sip是否有同名:");
//        while (iterator1.hasNext()){
//            String next = iterator1.next();
//            // System.out.println(next+"="+commonNameMap.get(next));
//        }//        downloadNetFile("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F2020-07-23%2F5f195601471b5.jpg&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1659774124&t=330917ba468613cc969d159e4a7d1a28","/Users/bindo/Downloads/OSDX-3/abc.gif");// System.out.println(extractSpId("SP59938s5t-_mop"));}
}

PFX文件解析及读取、写入、删除相关操作相关推荐

  1. 记:ELF文件解析初定义——Section段相关讲解

    0x00 概论 因为TI的DSP输出文件与传统的ELF文件不符,所以本人就顺道研究了一下现在的ELF的文件格式. 会将其陆续完成在文章中. 承接上文,上文书说到,解析文件头格式,数据段的分配定义,与数 ...

  2. php csv文件的读取,写入,输出下载操作详解

    2019独角兽企业重金招聘Python工程师标准>>> php对csv文件的读取,写入,输出下载操作. 代码: <?php $file = fopen('text.csv',' ...

  3. Python文件(一):文件类型、文件的打开,读取写入,关闭、文件备份、文件和文件夹的操作

    一.文件 文件是存储在存储器上的一组数据序列,可以包含任何数据内容. 文件是数据的抽象和集合. 二.文件类型 文本文件:长字符串 二进制是信息按照非字符但有特定格式形成的文件,文件内部数据的组织格式与 ...

  4. Java文件读写和CSV文件解析(读取csv文件的一列或若干列)

    文件类 Java 读文件流的知识不可少,先复习一下吧! OREACLE JDK8 DOCS 文件类是Java IO的一个对象,用于指定文件的相关信息,位置和名称信息.如txt文件,csv文件对Java ...

  5. pfx文件解析私钥和公钥

    最近和某行对接,发现私钥和公钥以pfx文件形式传给我们,需要我们自己进行读取,当时头就有点儿大(菜鸟,第一次接触,哎~~~) 先说一下pfx证书与cer证书的区别 PFX证书:由Public Key ...

  6. linux修改定时后如何保存文件夹,linux定时任务的一些相关操作汇总

    本人搜罗各大网站并测试了相关定时任务的操作方便大家进行查阅和操作. 1.cron介绍 我们经常使用的是 crontab 命令是cron table的简写,它是cron的配置文件,也可以叫它作业列表,我 ...

  7. Java笔记-读取资源文件应该注意的问题(大文件解析、\r\n分割相关的)

    目前在弄一个模拟程序,数据是从XXXXXXX里XXXXX获取的,也算是真实的把,将其放到资源文件中. 如下代码在IDEA开发环境里面是正常的: byte[] bytesxxx = new byte[i ...

  8. grib1文件解析 python_python读取grib格式数据

    python 读取grib/grib2格式数据 一般利用NCL(NCAR Command Language)读取.利用Python语言的pygrib库也可以读取grib/grib2格式数据 grib/ ...

  9. 关于C# 读取 写入 删除 注册表简单例子

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  10. php中下载csv文件怎么打开,php对csv文件的读取,写入,输出下载操作详解

    搜索热词 代码如下: PHP $file = fopen('text.csv','r'); while ($data = fgetcsv($file)) { //每次读取CSV里面的一行内容 //pr ...

最新文章

  1. 《转载》Java异常处理的10个最佳实践
  2. Spring Cloud Alibaba 高级特性 基于 Sleuth+Zipkin 实施链路跟踪体系
  3. 初涉c#设计模式-proxy pattern-从中国足球黑哨开始
  4. SonarQube的安装、配置与使用
  5. 深夜,我偷听到程序员要对session下手.......
  6. Django从理论到实战(part24)--在模板中访问静态文件
  7. C#各版本新增加功能
  8. mac 终端提示_有用的终端提示
  9. 解决 sublime text 3 there are no packages available for installation 错误
  10. 随想录(提高代码质量的几个工具)
  11. Linux_Qt:-1: error: cannot find xxx/lib: file format not recognized
  12. 频谱分析仪查看时域波形
  13. PyQt5最全27 绘图之drawLine绘制不同类型的直线
  14. uni-app开发小说阅读器
  15. 哈夫曼编码原理分析及代码实现(有注释)
  16. Zynq-Linux移植学习笔记之47-PL部分spi flash文件系统挂载
  17. 一步一步理解欧拉公式
  18. solid works旋转、抽壳的应用
  19. Android 10.0去掉后台启动Service的限制
  20. Java 常用工具类 Collections 源码分析

热门文章

  1. IceSword 1.18 by PJF
  2. message_filters学习笔记
  3. 理财中的六大心理学效应(一)
  4. 软件测试——界面测试
  5. Codeforces edu round 61 D-Stressful Training 二分
  6. 口袋妖怪金心银魂详细图文攻略(上)及游戏下载
  7. HTML+CSS---进阶学习03
  8. Chapter 2 (Discrete Random Variables): Probability mass functions (PMF 分布列)
  9. 一个专门帮助前端搞副业的社群
  10. metasploit的SET的Credential Harvester Attack Method