Certificate数字证书的有效性验证

1.证书相关概念

        在讲证书有效性验证的逻辑之前,先了解几个概念。

  1.  证书颁发机构:一般为运营数字证书的机构,该机构负责证书的签发、吊销等生命周期管理。
  2. 证书链:证书颁发机构一般会由多个组成,为树状层级,第一级的机构证书叫根证书、第二级叫二级子CA证书,多个层级的机构证书组成一个文件叫证书链(后缀为:.p7b)。
  3. 吊销列表:由证书颁发机构发布,若证书过期或因某些原因(密钥泄漏)吊销,则会将该证书添加至吊销列表。吊销列表为一个文件,包含已吊销的证书序列号(后缀为:.crl)。

2.证书相关概念

        数字证书的有效性验证分为三个步骤:

        1.验证证书的有效期,证书的有效期是一个时间短,需验证当前使用证书的时间不早于开始时间,不晚于结束时间。

        2.证书链的验证:验证证书是否由合法的机构签发的。

        2.验证证书签发机构发布的吊销列表是否包含当前证书,若包含,则当前证书已不可用,为无效证书。

3.使用场景

        一般我们在调用https的服务接口时,会做证书的有效性校验。避免证书过期或因密钥泄漏后仍在使用。造成不安全的因素。

4.代码案例

依赖的jar包坐标如下:

        <dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15to18</artifactId><version>1.68</version></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcpkix-jdk15to18</artifactId><version>1.68</version></dependency>

以下为代码实现

    //以下静态块不能省略static {if(Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {Security.addProvider(new BouncyCastleProvider());}}/*** 验证用户证书的有效性,包括验证有效期、证书信任列表、吊销状态等** @param certFile       用户证书* @param certChainFile  证书链文件* @param crlFile        证书吊销列表文件* @throws CertificateNotYetValidException 证书未生效* @throws CertificateExpiredException     证书已过期* @throws SignatureException              证书不被信任* @throws IsRevokedException 证书被吊销*/public static void verifyCertificate(File certFile, File certChainFile, File crlFile) throws CertificateNotYetValidException, CertificateExpiredException,IsRevokedException, CertificateEncodingException {X509Certificate certificate = CertFileUtil.getCertificate(certFile);certificate.checkValidity();CertPath certPath = null;try {certPath = CertFileUtil.getCertPath(certChainFile);} catch (CertificateException e) {e.printStackTrace();throw new CommonException("证书链读取异常,原因:"+e.getMessage());}catch (FileNotFoundException e){throw new CommonException("未找到证书链文件,原因:"+e.getMessage());}List<X509Certificate> certList = (List<X509Certificate>) certPath.getCertificates();boolean flag = false;for(X509Certificate caCert : certList) {if(certificate.getIssuerX500Principal().equals(caCert.getSubjectX500Principal())) {//使用机构证书验签用户证书flag = verify(caCert.getPublicKey(),certificate);if(flag) {break;}}}if(!flag) {throw new CommonException("证书链验证证书签名失败");}X509CRL crlObj = CertFileUtil.getCrl(crlFile);if(crlObj.isRevoked(certificate)){X509CRLEntry crlEntry = crlObj.getRevokedCertificate(certificate);throw new IsRevokedException(crlEntry.getRevocationReason());}}private static boolean verify(PublicKey publicKey,X509Certificate certObj) {byte[] signValue = certObj.getSignature();byte[] data = null;try {data = certObj.getTBSCertificate();} catch (CertificateEncodingException e) {throw new CommonException("证书格式错误,未获取到证书内容,原因:"+e.getMessage(),e);}//获取签名算法的OIDAlgorithmIdentifier oid = new AlgorithmIdentifier(new ASN1ObjectIdentifier(certObj.getSigAlgOID()), DERNull.INSTANCE);String signName = new DefaultAlgorithmNameFinder().getAlgorithmName(oid);return verificationSignature(publicKey.getEncoded(), signName, signValue,data);}/*** 数字签名验签* @param publicKey 公钥(PKCS8编码的私钥字节数组,可参考非对称密钥对的生成接口返回结果。)* @param signAlg 签名算法* @param signValue 签名值* @param data 签名值的原文* @return true为验签通过,表示签名者是合法的。false为验证未通过,签名者为非法。*/private static boolean verificationSignature(byte[] publicKey, String signAlg, byte[] signValue,byte[] data)throws CryptoException{PublicKey key = null;if(signAlg.endsWith("RSA")) {key = SoftwareKeyUtil.bytesToPublicKey(publicKey, "RSA");}else{key = SoftwareKeyUtil.bytesToPublicKey(publicKey, "SM2");}Signature inSignatue = null;try {inSignatue = Signature.getInstance(signAlg, BouncyCastleProvider.PROVIDER_NAME);} catch (NoSuchAlgorithmException e) {e.printStackTrace();throw new CryptoException("未找到算法",e);}catch (NoSuchProviderException e){throw new CryptoException("未找到安全程序提供商,原因:"+e.getMessage(),e);}try {inSignatue.initVerify(key);} catch (InvalidKeyException e) {e.printStackTrace();throw new CryptoException("无效的公钥",e);}try {inSignatue.update(data);} catch (SignatureException e) {e.printStackTrace();throw new CryptoException("签名更新数据异常",e);}try {return inSignatue.verify(signValue);} catch (SignatureException e) {e.printStackTrace();throw new CryptoException("签名异常",e);}}

测试代码:以下代码只要未出现异常,则为证书有效性验证通过。

public static void main(String[] args) {try {CertificateUtil.verifyCertificate(new File("/home/zhangzz/Downloads/_.csdn.crt"),new File("/home/zhangzz/Downloads/GeoTrust CN RSA CA G1.p7c"));System.out.println("证书有效");} catch (CertificateNotYetValidException e) {System.out.println("证书有效期未开始,请待进入有效期后开始使用:" + e.getMessage());} catch (CertificateExpiredException e) {System.out.println("证书已过期:" + e.getMessage());}}

在数字证书里,是可以看到证书链的http下载地址及吊销列表的下载地址的。如下图:

证书链地址:已CSDN的证书为例,它的上一级就是当前证书的颁发机构证书,可以导出为证书链。

点击*.csdn.net这个证书,它的证书属性里有授权信息访问,该属性为颁发机构的信息,其中CA颁发者就是该机构的CA证书,也可以用该证书直接作为证书链去验证。

具体如何使用代码从证书里获取证书链和吊销列表文件,无需手动更新。这个问题我们下次再分解。

以上的代码可以在git中获取(若未找到代码,请切换dev分支),代码路径:com.zhangzz.crypto.utils.CertificateUtil.java

加密工具starter组件git地址

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

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

相关文章

JWT整合Gateway实现鉴权(RSA与公私密钥工具类)

一.业务流程 1.使用RSA生成公钥和私钥。私钥保存在授权中心&#xff0c;公钥保存在网关(gateway)和各个信任微服务中。 2.用户请求登录。 3.授权中心进行校验&#xff0c;通过后使用私钥对JWT进行签名加密。并将JWT返回给用户 4.用户携带JWT访问 5.gateway直接通过公钥解密JWT进…

数据库 | 试卷五试卷六试卷七

1. 主码不相同&#xff01;相同的话就不能唯一标识非主属性了 2.从关系规范化理论的角度讲&#xff0c;一个只满足 1NF 的关系可能存在的四方面问题 是&#xff1a; 数据冗余度大&#xff0c;插入异常&#xff0c;修改异常&#xff0c;删除异常 3.数据模型的三大要素是什么&…

15. STUN协议和ICE工作原理

NET介绍 NAT是一种地址转换技术&#xff0c;它可以将IP数据报文头中的IP地址转换为另一个IP地址&#xff0c;并通过转换端口号达到地址重用的目的。 在大多数网络环境中&#xff0c;我们都需要通过 NAT 来访问 Internet。 NAT作为一种缓解IPv4公网地址枯竭的过渡技术&#xff…

AMBA-CHI协议详解(三)

《AMBA 5 CHI Architecture Specification》 AMBA-CHI协议详解&#xff08;一&#xff09; AMBA-CHI协议详解&#xff08;二&#xff09; AMBA-CHI协议详解&#xff08;三&#xff09; AMBA-CHI协议详解&#xff08;四&#xff09; 文章目录 2.3.2 Write transactions2.3.2.1 …

keil5显示内存和存储占用百分比进度条工具

简介 [Keil5_disp_size_bar] 以进度条百分比来显示keil编译后生成的固件对芯片的内存ram和存储flash的占用情况, 并生成各个源码文件对ram和flash的占比整合排序后的map信息的表格和饼图。 原理是使用C语言遍历当前目录找到keil工程和编译后生成的map文件 然后读取工程文件和m…

若依框架自定义开发使用学习笔记(1)

因为我是跳着学的&#xff0c;原理那些都没咋看。 代码自动生成&#xff0c;依赖sql表 在ruoyi数据库中&#xff0c;创建你想要的表&#xff0c;这里我创建了个购物车表&#xff0c;由于空间有限&#xff0c;只能拍到这么多。 然后就可以在前端自动生成代码 点击导入按钮 …

创新入门 | 病毒循环Viral Loop是什么?为何能实现指数增长

今天&#xff0c;很多高速增长的成功创业公司都在采用”病毒循环“的策略去快速传播、并扩大用户基础。究竟什么是“病毒循环”&#xff1f;初创公司的创始人为何需要重视这个策略&#xff1f;这篇文章中将会一一解答与病毒循环有关的各种问题。 一、什么是病毒循环&#xff08…

【Ruby基础01】windows和termux中搭建Ruby开发环境

windows下环境搭建 railsinstaller官方git地址 按照文档安装git、nodejs、yarn&#xff0c;安装教程百度一下。railsinstall可以从release页面下载最新版本4.1.0。 安装完成如下 安装RubyMine 下载RubyMine RubyMine下载地址 安装激活 下载文件&#xff0c;按照里面的流程…

Java 读取Excel导入数据库,形成树状结构

最近开发过程中遇到一个Excel的导入的功能,因为导入的数据结构具有层次结构,经过一番研究,最终得以实现,所有写下该文章,记录过程,供以后参考。 下图是导入Excel的数据结构: 使用POI解析Excel,数据封装然后进行入库。下面是核心代码。 @Overridepublic KnowledgeBase…

示例:WPF中如何不卡顿页面的情况加载大量数据

一、目的&#xff1a;在开发过程中经常会遇到一个ListBox列表里面需要加载大量数据&#xff0c;但是加载过程中会假死卡顿影响用户体验&#xff0c;或者是你的主页面加载了大量控件&#xff0c;或者切换到一个有大量元素的页面都会有这种体验&#xff0c;因为加载的都是UI元素不…

基于matlab的RRT算法路径规划(附带案例源码)

文章中的所有案例均为博主手动复现&#xff0c;用于记录博主学习路径规划的过程&#xff0c;如有不妥&#xff0c;欢迎在评论区交流 目录 1 标准RRT1.1 算法原理1.2 演示 2 GBRRT2.1 算法原理2.2 算法演示 3 RRT-STAR3.1 算法原理3.2 算法演示 4 RRT-CONNECT4.1 算法原理4.2 算…

了解指标体系1:指标是大数据开发中的关键要素

在大数据开发的过程中&#xff0c;指标体系是一个至关重要的概念。本文将介绍什么是指标&#xff0c;为什么它们如此重要&#xff0c;以及如何在大数据项目中有效地构建和应用指标体系。 目录 什么是指标&#xff1f;指标的类型为什么指标如此重要&#xff1f;如何构建有效的指…

Swift开发——存储属性与计算属性

Swift语言开发者建议程序设计者多用结构体开发应用程序。在Swift语言中,结构体具有了很多类的特性(除类的与继承相关的特性外),具有属性和方法,且为值类型。所谓的属性是指结构体中的变量或常量,所谓的方法是指结构体中的函数。在结构体中使用属性和方法是因为:①匹别于结…

每日一练:攻防世界:miao~

给了一张jpg图片 没发现什么特别&#xff0c;放到winhex中查看也没思路。 放到kali里面foremost分离文件试试&#xff0c;结果分离出个wav音频文件 直接放到 audycity看看频谱图 发现字符串&#xff0c;但是没有其他信息。可能是密钥之类的。到这里我就卡住了&#xff0c;看…

镜像拉取失败:[ERROR] Failed to pull docker image

问题描述 执行 bash docker/scripts/dev_start.sh 命令提示错误&#xff1a; permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post “http://%2Fvar%2Frun%2Fdocker.sock/v1.45/images/create?fromImageregistry.b…

微信小程序-上拉加载和下拉刷新

一.上拉加载 微信小程序的上拉加载使用onReachBottom()&#xff0c;写在.js文件里面的Page方法里面。 onReachBottom(){//上拉自动更新到4&#xff0c;5&#xff0c;6wx.showLoading({title: 数据加载中...,})setTimeout(()>{const lastNumthis.data.numList[this.data.nu…

Ubuntu网络管理命令:nslookup

安装Ubuntu桌面系统&#xff08;虚拟机&#xff09;_虚拟机安装ubuntu桌面版-CSDN博客 nslookup命令主要用来查询域名信息&#xff0c;实际上主要是将域名转换为相应的IP地址&#xff0c;或者将IP地址转换成相应的域名。nslookup命令为用户提供了两种工作模式&#xff0c;分别…

matlab线性多部法求常微分方程数值解

用Adamas内差二步方法&#xff0c;内差三步方法&#xff0c;外差二步方法&#xff0c;外差三步方法这四种方法计算。 中k为1和2. k为2和3 代码 function chap1_adams_methodu0 1; T 2; h 0.1; N T/h; t 0:h:T; solu exact1(t);f f1; u_inter_2s adams_inter_2steps(…

项目训练营第二天

项目训练营第二天 用户登录逻辑 1、账户名不少于4位 2、密码不少于8位 3、数据库表中能够查询到账户、密码 4、密码查询时用同样加密脱敏处理手段处理后再和数据库中取出字段进行对比&#xff0c;如果账户名未查询到&#xff0c;直接返回null 5、后端设置相应的脱敏后用户的s…

就因为没在大屏项目加全屏按钮,早上在地铁挨了领导一顿骂

“嗯嗯”&#xff0c;“嗯嗯”&#xff0c;“那产品也没说加呀”&#xff0c;“按F11不行吗&#xff1f;”&#xff0c;“嗯嗯”&#xff0c;“好的”。 早上在4号线上&#xff0c;我正坐在地铁里&#xff0c;边上站着的妹子&#xff0c;我看他背着双肩包&#xff0c;打着电话…