java 解析p12证书 (获取公钥、私钥、序列号)

news2024/11/24 10:25:47

          

1. p12文件放在resources目录下

 
2. P12InfoVo

import lombok.Builder;
import lombok.Data;

import java.io.Serializable;
import java.security.PrivateKey;
import java.security.PublicKey;


/**
 * p12证书VO
 */
@Data
@Builder
public class P12InfoVo implements Serializable{

    /**
     * 证书公钥
     */
    private final PublicKey publicKey;

    /**
     * 证书私钥
     */
    private final PrivateKey privateKey;

    /**
     * 证书序列号
     */
    private final String serialNo;
}

3. P12Utils

import com.ruoyi.ruoyils.utils.WxPayUtils;
import org.junit.Test;
import sun.security.x509.X509CertImpl;
import java.io.FileInputStream;
import java.math.BigInteger;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.util.Enumeration;


/**
 *
 * PKCS12证书中解析公钥、私钥、证书序列号
 *
 * apiclient_cert.p12
 *
 */
public class P12Utils {


    @Test
    public void test(){
        // p12证书路径
        String path = "D:\\Java\\work\\ChenXinCode\\light_show\\ruoyi-admin\\src\\main\\resources\\apiclient_cert.p12";
        P12InfoVo vo = this.parse(path, WxPayUtils.mchId);

        System.out.println("证书公钥: " + vo.getPublicKey());
        System.out.println("证书私钥: " + vo.getPrivateKey());
        System.out.println("证书序列号: " + vo.getSerialNo());
    }

    /**
     * 解析p12文件
     *
     * @param p12Path   证书文件路径
     * @param passwd    证书密码 (也就是商户号)
     * @return
     */
    public static P12InfoVo parse(String p12Path, String passwd) {
        try {
            // 获取文件流
            FileInputStream is = new FileInputStream(p12Path);

            KeyStore ks = KeyStore.getInstance("PKCS12");
            ks.load(is, passwd.toCharArray());
            String keyAlias = null;
            //解析证书,必须有别名
            Enumeration<String> aliases = ks.aliases();
            if (aliases.hasMoreElements()) {
                keyAlias = aliases.nextElement();
            }
            //解析私钥
            PrivateKey privateKey = (PrivateKey) ks.getKey(keyAlias, passwd.toCharArray());
            Certificate cert = ks.getCertificate(keyAlias);
            BigInteger serialNumber = ((X509CertImpl) cert).getSerialNumber();
            //证书一般都使用16进制表示
            String certSn = serialNumber.toString(16).toUpperCase();

            //设置证书公钥、私钥、序列号
            return P12InfoVo.builder()
                    .publicKey(cert.getPublicKey())
                    .privateKey(privateKey)
                    .serialNo(certSn)
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/874922.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最强自动化测试框架Playwright(17)- 模拟接口

模拟接口 介绍 Web API 通常作为 HTTP 终结点实现。Playwright提供了API来模拟和修改网络流量&#xff0c;包括HTTP和HTTPS。页面所做的任何请求&#xff0c;包括 XHR 和获取请求&#xff0c;都可以被跟踪、修改和模拟。使用Playwright&#xff0c;您还可以使用包含页面发出的…

生信豆芽菜-单基因与HRD评分的关系

网址&#xff1a;http://www.sxdyc.com/panCancerHRDScore 该工具主要用于查看单基因在泛癌中与HRD评分的相关性 提交后等待运行成功即可

Qt4/5升级到Qt6吐血经验总结V202308

00&#xff1a;直观总结 增加了很多轮子&#xff0c;同时原有模块拆分的也更细致&#xff0c;估计为了方便拓展个管理。把一些过度封装的东西移除了&#xff08;比如同样的功能有多个函数&#xff09;&#xff0c;保证了只有一个函数执行该功能。把一些Qt5中兼容Qt4的方法废弃…

IDEA项目实践——JavaWeb简介以及Servlet编程实战

系列文章目录 IDEA项目实践——创建Java项目以及创建Maven项目案例、使用数据库连接池创建项目简介 IDEWA项目实践——mybatis的一些基本原理以及案例 IDEA项目实践——动态SQL、关系映射、注解开发 IDEA项目实践——Spring框架简介,以及IOC注解 IDEA项目实践——Spring当…

利用ViewModel和LiveData进行数据管理

利用ViewModel和LiveData进行数据管理 1. 引言 在当今移动应用开发的世界中&#xff0c;数据管理是一个至关重要的方面。随着应用的复杂性不断增加&#xff0c;需要有效地管理和维护应用中的数据。无论是从服务器获取数据、本地数据库存储还是用户界面的状态&#xff0c;数据…

Python方式实现射后不管导弹的简易制导系统

1 问题 对QN-506上的S570智能反坦克制导导弹的射后不管产生了浓厚的兴趣&#xff0c;想用Python简易还原一下。 2 方法 之前查阅资料时了解到使用pygame库制作的贪吃蛇&#xff0c;是否有一种方法能让“贪吃蛇”一直跟着鼠标走呢&#xff1f;鼠标模拟行进中的坦克&#xff0c;“…

劝你入行嵌入式的五个理由

嵌入式技术作为一个备受瞩目的领域&#xff0c;已经吸引了越来越多的人才。如果您还在考虑是否要进入该领域&#xff0c;我建议您听听以下五个理由&#xff1a; 一、市场需求旺盛 随着科技的迅猛发展&#xff0c;嵌入式系统已经广泛渗透到我们生活的各个方面。从智能家居到智能…

rabbitmq的持久化

目录 队列实现持久化 如何删除队列​编辑 消息实现持久化 不公平分发 如何保障当 RabbitMQ 服务停掉以后消息生产者发送过来的消息不丢失。默认情况下 RabbitMQ 退出或由于某种原因崩溃时&#xff0c;它忽视队列和消息&#xff0c;除非告知它不要这样做。确保消息不会丢失需…

浅析前端请求登录与后台对接

首先确保前后端接口参数一致&#xff0c;我这里使用的是ant design Pro 前端框架 小技&#xff1a;shiftf6&#xff0c;全局重构&#xff0c;当接口不一致时很方便 前&#xff1a; 后&#xff1a; 前后端交互&#xff1a;前端需要向后端发送请求&#xff0c;前端ajax来请求后…

Ubuntu虚拟机增加交换内存

接下来增加交换内存。配置交换内存&#xff0c;需要用户根据自己的实际情况进行配置。这里举例分配 5G 交换内存。 在开始之前&#xff0c;使用命令检查一下您的 ubuntu 的 swap 分区&#xff0c;可以看到交换分区为 2G &#xff0c;如下图所示&#xff1a; sudo swapon …

【ChatGPT 指令大全】怎么使用ChatGPT来辅助知识学习

目录 概念解说 简易教学 深度教学 教学与测验 解释一个主题的背后原理 总结 在当今信息时代&#xff0c;互联网的快速发展为我们获取知识提供了前所未有的便利。而其中&#xff0c;人工智能技术的应用也为我们的学习和交流带来了新的可能性。作为一种基于自然语言处理的人…

(css)点击前隐藏icon图表 点击后显示

(css)点击前隐藏icon图表 点击后显示 效果 html <liv-for"(item,index) in sessionList":key"index"class"liClass":class"{ active: change2 index }"tabindex"2">...<el-tooltip class"item" effec…

双驱拖挂底盘的制作分享

1. 运动功能说明 本文示例将实现R331样机双驱拖挂底盘运动的功能。 2. 结构说明 双驱拖挂底盘是一种具有两个驱动轴的车辆底盘&#xff0c;它由两个驱动轴、悬挂系统、转向系统和连接拖车的结构组成。以下是一些关于双驱拖挂底盘的主要特点和优势&#xff1a; ① 强大的牵引能力…

网络基础-PosixAPI

文章目录 一.网络常用接口Linux协议栈与posix api的关系 背景1.1 socket1.8 close服务端posix接口1.2 bind1.3 listen1.4 accept1.5 connect1.6 send1.7 recv总结 二. 修改句柄属性2.1 fctl2.2 特殊作用2.2.1 设置阻塞非阻塞2.2.1 实例2.2.2设置获取记录锁2.2.2 实例 三、文件操…

苹果恢复已删除的照片,3种超实用教程!

【大家帮帮孩子吧&#xff01;去旅游拍的写真不小心被我删掉了&#xff0c;回收站也找不到&#xff0c;有什么办法能恢复回来吗&#xff1f;】 不小心误删了重要照片该怎么办&#xff1f;大家都知道&#xff0c;苹果手机【最近删除】里的照片只能保留30天&#xff0c;超过了这…

CAD版本怎么在线转换?教你在线转换CAD版本方法

CAD文件版本转换通常是由于文件的创建者使用了与接收者不同的CAD软件版本。此外&#xff0c;如果接收者使用的CAD软件版本与创建者使用的版本不兼容&#xff0c;则可能需要进行文件版本转换&#xff0c;以便接收者能够正确地查看和编辑文件。很多小伙伴喜欢在线处理文件格式&am…

《零基础实践深度学习》(第2版)学习笔记,(五)深度学习与计算机视觉

文章目录 1. 计算机视觉概述2. 图像分类3. 目标检测 1. 计算机视觉概述 图像分类 目标检测 2. 图像分类 3. 目标检测

Guitar Pro8专业版吉他学习、绘谱、创作软件

Guitar Pro 8 专业版更强大&#xff01;更优雅&#xff01;更完美&#xff01;Guitar Pro 8.0 五年磨一剑&#xff01;多达30项功能优化&#xff01;Guitar Pro8 版本一共更新近30项功能&#xff0c;令吉他打谱更出色&#xff01;Guitar Pro8 是自2017年4月发布7.0之后发布的最…

独立游戏开发者的工具栈【Lumnis作者】

作为一名单人游戏开发者&#xff0c;需要成为多面手。 如果你想避免委托给承包商&#xff0c;需要身兼数职&#xff0c;并精通艺术、编程、游戏设计、音乐创作、营销等&#xff0c;具体取决于你制作的游戏。 学习所有这些需要时间和练习&#xff0c;但也需要金钱。 大多数游戏…

thread 的join方法

join方法的底层执行&#xff1f; 看如测试用例&#xff1a; -> 两个红色的框分别说明了sleep方法前后test01的状态&#xff0c;这个不是重点&#xff0c;只是一个验证而已。 重要的是test02的状态&#xff0c;调用join方法后&#xff0c;test02变成了WAITING状态&#xff…