当前位置: 首页 > news >正文

certificate-transparency-go用例

文章目录

  • 证书的SCT列表
  • 验证SCT
    • 依赖包
    • 加载证书
    • 初始化log机构信息
    • 离线验证+在线验证

证书的SCT列表

浏览器对证书链的合法性检查通过后,会再检查服务端证书附件里的SCT列表(Signed Certificate Timestamp);
浏览器内置了一批certificate transparency log机构的公钥和访问地址,如果SCT申明证书在某个log机构注册了,但是SCT里的签名通过不了log机构的公钥验证,则抛出错误NET::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED

验证SCT

依赖包

使用github.com/google/certificate-transparency-go工具

import ("context""encoding/base64""encoding/pem""errors""io""log""net/http""os""time"ct "github.com/google/certificate-transparency-go""github.com/google/certificate-transparency-go/ctutil""github.com/google/certificate-transparency-go/loglist3"ctX509 "github.com/google/certificate-transparency-go/x509""github.com/google/certificate-transparency-go/x509util"
)

加载证书

假设服务端证书以及签发该证书的上级CA证书,已保存为PEM格式的文件

func VerifySCT(certLocation string, issuerLocation string) error {// 服务端证书certByte, err := os.ReadFile(certLocation)if err != nil {return err}block, _ := pem.Decode(certByte)if block == nil || len(block.Bytes) == 0 {return errors.New("error decoding certificate")}cert, err := ctX509.ParseCertificate(block.Bytes)if err != nil {return err}// 上级CAcertByte, _ = os.ReadFile(issuerLocation)block, _ = pem.Decode(certByte)if block == nil || len(block.Bytes) == 0 {return errors.New("error decoding issuer CA")}issuer, _ := ctX509.ParseCertificate(block.Bytes)err = cert.CheckSignatureFrom(issuer)if err != nil {log.Printf("证书%s的签名算法是%s,CA签名没有验证成功", cert.Subject, cert.SignatureAlgorithm.String())return err}// 生成merkle tree leaf,用于验证sct(Signed Certificate Timestamp)merkleLeaf, err := ct.MerkleTreeLeafForEmbeddedSCT([]*ctX509.Certificate{cert, issuer}, 0)if err != nil {return err}// 获取证书里附带的sct列表sctList, err := x509util.ParseSCTsFromSCTList(&cert.SCTList)if err != nil {log.Printf("ParseCertificate failed %v", err)return err}log.Printf("验证证书%s的SCT列表", cert.Subject)

初始化log机构信息

使用和chrome一致的机构列表:https://www.gstatic.com/ct/log_list/v3/log_list.json

	// 获取chrome使用的certificate transparency log机构列表,包含机构使用的公钥和查询api地址resp, err := http.DefaultClient.Get(loglist3.LogListURL)if err != nil {return errors.New("下载certificate transparency log地址列表失败")}defer resp.Body.Close()body, err := io.ReadAll(resp.Body)if err != nil {return errors.New("下载certificate transparency log地址列表失败")}loglistEntry, _ := loglist3.NewFromJSON(body)logsByHash, _ := ctutil.LogInfoByKeyHash(loglistEntry, http.DefaultClient)

离线验证+在线验证

logInfo.VerifySCTSignature方法不需要和log机构在线交互,是使用已知的log机构公钥对SCT进行离线验证

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel()for _, sct := range sctList {// 验证sct,参考https://github.com/google/certificate-transparency-go/blob/master/ctutil/sctscan/sctscan.golog.Printf("sct signature: %s, %s", base64.StdEncoding.EncodeToString(sct.Signature.Signature), time.Unix(0, int64(sct.Timestamp)*int64(time.Millisecond)).Format(time.RFC3339Nano))logInfo, ok := logsByHash[sct.LogID.KeyID]if !ok {log.Printf("sct key_hash: %s,不存在对应certificate transparency log机构", base64.StdEncoding.EncodeToString(sct.LogID.KeyID[:]))continue}log.Printf("颁发sct的certificate transparency log机构是: %s,地址:%s, 公钥哈希:%s", logInfo.Description,logInfo.Client.BaseURI(), base64.StdEncoding.EncodeToString(sct.LogID.KeyID[:]))err = logInfo.VerifySCTSignature(*sct, *merkleLeaf)if err != nil {log.Printf("Verify SCT failed %v", err)continue}log.Println("Verify SCT offline OK")// 线上验证,非必须if _, err := logInfo.VerifyInclusionLatest(ctx, *merkleLeaf, sct.Timestamp); err != nil {sth := logInfo.LastSTH()if sth != nil {delta := time.Duration(sth.Timestamp-sct.Timestamp) * time.Millisecondif delta < logInfo.MMD {// 如果生效时间(logInfo.MMD)还未到,那么机构查询不到该sct的merkle tree leaf信息是正常的log.Printf("SCT's MMD has not passed %d -> %d < %v", sct.Timestamp, sth.Timestamp, logInfo.MMD)continue}}log.Printf("Failed to verify SCT online: %v", err)} else {log.Println("Verify SCT online OK")}}

每个SCT分别是不同log机构签发的,如果一个证书附带的两个SCT是由同一个log机构签发,或者SCT列表涉及的log机构合计不足3个,浏览器似乎也会报错;
目前,证书检查通过后,chrome的F12里才显示解析的SCT列表;ERR_CERTIFICATE_TRANSPARENCY_REQUIRED错误发生时,需要使用这个程序来查看SCT列表里是否存在重复注册、注册的log机构数量不足,甚至是否无法通过SCT签名检查

相关文章:

certificate-transparency-go用例

文章目录 证书的SCT列表验证SCT依赖包加载证书初始化log机构信息离线验证在线验证 证书的SCT列表 浏览器对证书链的合法性检查通过后&#xff0c;会再检查服务端证书附件里的SCT列表&#xff08;Signed Certificate Timestamp&#xff09;&#xff1b; 浏览器内置了一批certif…...

前端上传大文件使用分片上传

前提:分片上传针对于一些大的文件、普通大小的文件使用element中的上传组件可以实现效果,例如几G的文件就会比较卡,所以这时候就需要用到分片上传~ 前端及后端分片上传笔记 效果:(上传进度展示) 效果:(上传成功的效果展示) 1、 新建一个上传组件 2、使用vue-simple-…...

Kotlin 解构声明

在一些像 Python 的高级语言中&#xff0c;支持 多返回值的&#xff0c;例如 x, y get_position() 这样操作接收。 而在 Kotlin 中&#xff0c;虽然不支持 多返回值&#xff0c;但有类似的 解构&#xff08;destructure&#xff09; 对象功能&#xff0c;叫做 解构声明。 用…...

基于若依的ruoyi-nbcio流程管理系统一种简单的动态表单模拟测试实现(四)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/n…...

遗传算法原理详细讲解(算法+Python源码)

博主介绍&#xff1a;✌专研于前后端领域优质创作者、本质互联网精神开源贡献答疑解惑、坚持优质作品共享、掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战&#xff0c;深受全网粉丝喜爱与支持✌有需要可以联系作者我哦&#xff01; &#x1f345;文末获…...

Linux文本处理指令汇总

Linux文本处理命令主要包括以下几种&#xff1a; grep&#xff1a;用于在文件中搜索包含指定字符串的行。 [roothanyw-bash-python ~]# grep root /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologinawk&#xff1a;用于在文件中进行…...

Prompt Engineering

目录 什么是提示工程 什么是提示工程 在当今人工智能领域&#xff0c;提问大型语言模型&#xff08;Large Language Models&#xff0c;LLM&#xff09;已经成为一种常见的实践&#xff0c;但如何向这些模型提出问题&#xff0c;或者更准确地说&#xff0c;如何引导它们产生期…...

Ansible剧本playbooks

playbooks概述 Ansible剧本&#xff08;playbook&#xff09;是用于配置、部署和管理被控节点的一种描述文件。通过编写详细的剧本描述和执行其中的任务&#xff08;tasks&#xff09;&#xff0c;可以使远程主机达到预期的状态。剧本由一个或多个"play"组成的列表构…...

Excel·VBA时间范围筛选及批量删除整行

看到一个帖子《excel吧-筛选开始时间&#xff0c;结束时间范围内的所有记录》&#xff0c;根据条件表中的开始时间和结束时间构成的时间范围&#xff0c;对数据表中的开始时间和结束时间范围内的数据进行筛选 目录 批量删除整行&#xff0c;整体删除批量删除整行&#xff0c;分…...

Map转成String,String 转换成Map

一、使用场景 把一个map转换成json字符串后存放在Redis中&#xff0c;然后在redis中取出json字符串&#xff0c;再把字符串转变成原来的Map 二、具体实现 1.1 Map转成String 这里使用是阿里巴巴fastjson Map<String, Object> reportData dssDashboardService.getRep…...

分享一个剧本(改编自我)

不知道是不是错过了一个喜欢我的女孩&#xff0c;一个很不错的女孩&#xff0c;当初没勇气表白。去年表白过但女孩表示仅想是永远的朋友&#xff0c;今天翻他的朋友圈发现2021年我生日时&#xff0c;她分享了这首歌曲&#xff0c;还评论Best wishes!!!&#xff0c;高中有一次我…...

结合Tensuns管理prometheus的blackbox与告警设置

场景说明&#xff1a; 因为业务服务器已经完成了三级等保&#xff0c;禁止在业务服务器上部署任何应用&#xff0c;遂选择一台新的服务器部署prometheus&#xff0c;采用blackbox_exporter监控业务服务器的端口与域名状态。 Tensuns项目介绍 https://github.com/starsliao/T…...

printf实现

这是我看之前公司的旧代码摘录下来的, 感觉写的还算可以吧, void printfsend(UART_TypeDef UARTx, uint8_t *buf, int len) {uint8_t printbuf[256];for (int i 0; i < len; i){printbuf[i] buf[i];}#ifdef ENABLE_PERIAL_TESTif (uart_printf_switch_gloab){UART_Send…...

Elasticsearch 中的 term、terms 和 match 查询

目录 term 查询 terms 查询 match 查询 注意事项 结论 Elasticsearch 提供了多种查询类型&#xff0c;用于不同的搜索需求。term、terms 和 match 是其中最常用的一些查询类型。下面分别介绍每种查询类型的用法和特点。 term 查询 term 查询用于精确值匹配。它通常用于关…...

美易官方:开盘:美股高开科技股领涨 标普指数创盘中新高

**开盘&#xff1a;美股高开科技股领涨 标普指数创盘中新高** 在周三的交易中&#xff0c;美国股市高开&#xff0c;科技股领涨市场&#xff0c;标普500指数创下盘中新高。投资者对经济复苏的乐观情绪以及对科技公司业绩的看好&#xff0c;共同推动了市场的上涨。 盘初&#xf…...

STM32F407移植OpenHarmony笔记2

接上篇&#xff0c;搭建完开发环境后&#xff0c;我们还要继续工作。 官方合作的开发板刚好有STM32F407&#xff0c;我准备试一下开发板的demo&#xff0c;虽然我用的不是他们的开发板。 先下载以下3份代码&#xff1a; https://gitee.com/openharmony/device_board_talkweb…...

数据仓库-相关概念

简介 数据仓库是一个用于集成、存储和管理大量数据的系统。它用于支持企业决策制定过程中的数据分析和报告需求。数据仓库从多个来源收集和整合数据&#xff0c;并将其组织成易于查询和分析的结构。 数据仓库的主要目标是提供高性能的数据访问和分析能力&#xff0c;以便…...

线程的面试八股

​ Callable接口 Callable是一个interface,相当于给线程封装了一个返回值,方便程序猿借助多线程的方式计算结果. 创建一个匿名内部类, 实现 Callable 接口. Callable 带有泛型参数. 泛型参数表示返回值的类型. 重写 Callable 的 call 方法, 完成累加的过程. 直接通过返回值返…...

Jmeter 配置元件

Jmeter 配置元件 CSV 数据集配置HTTP Cookie 管理器HTTP Header 信息头管理器增加多个用户案列 使用Jmeter发送请求的时候&#xff0c;需要配置元件&#xff0c;配置请求Header、Cookie、数据集合等。可以模拟多个在线用户登录&#xff0c;修改请求头数据。 CSV 数据集配置 C…...

Java- @FunctionalInterface声明一个接口为函数式接口

基本介绍 FunctionalInterface 是 Java 8 中引入的注解&#xff0c;用于声明一个接口是函数式接口。函数式接口是指仅包含一个抽象方法的接口&#xff0c;可以用于支持 Lambda 表达式和方法引用。FunctionalInterface 注解确保该接口只包含一个抽象方法&#xff0c;从而确保其…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)

目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 ​编辑​编辑 UDP的特征 socke函数 bind函数 recvfrom函数&#xff08;接收函数&#xff09; sendto函数&#xff08;发送函数&#xff09; 五、网络编程之 UDP 用…...