当前位置: 首页 > 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;从而确保其…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...