当前位置:首页 > 文章列表 > Golang > Go教程 > Go crypto/mlkem 怎样封装后量子密钥协商

Go crypto/mlkem 怎样封装后量子密钥协商

来源:17golang原创 2026-10-20 05:15:48 0浏览 收藏

Go crypto/mlkem 可以把后量子密钥建立封装成三个职责:接收侧生成并保管解封装私钥,发送侧使用公开封装密钥生成共享秘密及密文,接收侧用私钥解封装密文。网络上传的是公钥与封装密文,不是共享秘密。它不是业务明文加密函数,也不是带身份认证的完整握手协议。

Go 官方地址:https://go.dev/;标准库地址:https://pkg.go.dev/crypto/mlkem。

标准库提供的是 KEM 原语

Go 1.24 将 crypto/mlkem 加入标准库,实现 FIPS 203 定义的 ML-KEM;本文以 ML-KEM-768 为例,参见 Go 1.24 发布说明。示例使用该版本已有的具体类型接口,不依赖后续新增的通用封装接口。

KEM 的目标是建立共享秘密。NIST 的 FIPS 203 标准说明将它作为密钥封装机制,而非消息签名机制。若把业务字符串塞给 Encapsulate,接口本身就不匹配:该方法不接收业务明文,而是产生随机共享秘密及其封装密文。

先区分公钥、私钥与封装密文

在本文封装中,Receiver 持有 dk,PublicKey 只导出封装公钥,SealKey 的结果明确区分 ciphertext 与 secret。GenerateKey768 提供随机密钥生成,EncapsulationKey().Bytes() 提供公开编码;解封装私钥与共享秘密都要保密,详见 标准库接口文档。

材料本文变量或入口放置位置
解封装私钥dk接收侧内部
公开封装密钥PublicKey可公开,但接收方身份必须另行确认
封装密文ciphertext发给接收侧
共享秘密secret各端本地,不写日志
接收侧私钥与公开封装材料的分组结构
图1:原创静态结构图。接收侧秘密与公开材料分开,关系线仅标明持有、导出与封装依赖,不表示通信时序或运行结果。

用函数封装一次密钥建立

下面是同进程教学示例,用于理解两侧职责,没有网络层、身份认证或业务数据加密。Receiver 不允许零值直接使用,应从 NewReceiver 创建;示例未在本文环境执行,末尾文案仅为代码设定的成功分支。

package main

import (
    "bytes"
    "crypto/mlkem"
    "errors"
    "fmt"
)

// Receiver 只在接收侧持有解封装私钥,不把它装进网络消息。
type Receiver struct {
    dk *mlkem.DecapsulationKey768
}

func NewReceiver() (*Receiver, error) {
    dk, err := mlkem.GenerateKey768()
    if err != nil {
        return nil, fmt.Errorf("生成密钥: %w", err)
    }
    return &Receiver{dk: dk}, nil
}

// PublicKey 只导出公开封装密钥;不要改成 dk.Bytes()。
func (r *Receiver) PublicKey() []byte {
    return r.dk.EncapsulationKey().Bytes()
}

// SealKey 返回可传输密文与本地秘密,两者不能混成一个网络包。
func SealKey(public []byte) (ciphertext, secret []byte, err error) {
    ek, err := mlkem.NewEncapsulationKey768(public)
    if err != nil {
        return nil, nil, fmt.Errorf("解析封装公钥: %w", err)
    }
    // 标准库返回顺序是秘密在前、密文在后,此处显式重排。
    shared, ct := ek.Encapsulate()
    return ct, shared, nil
}

func (r *Receiver) OpenKey(ciphertext []byte) ([]byte, error) {
    // 输入长度检查在原语中完成;错误逐层返回,不生成替代密钥。
    secret, err := r.dk.Decapsulate(ciphertext)
    if err != nil {
        return nil, fmt.Errorf("解封装: %w", err)
    }
    return secret, nil
}

func demo() error {
    receiver, err := NewReceiver()
    if err != nil {
        return err
    }
    ct, senderSecret, err := SealKey(receiver.PublicKey())
    if err != nil {
        return err
    }
    receiverSecret, err := receiver.OpenKey(ct)
    if err != nil {
        return err
    }
    // 仅在同进程教学示例比较两端结果,不打印或传输秘密。
    if !bytes.Equal(senderSecret, receiverSecret) {
        return errors.New("示例密钥不一致")
    }
    return nil
}

func main() {
    if err := demo(); err != nil {
        fmt.Println("示例失败:", err)
        return
    }
    fmt.Println("示例密钥一致")
}

这里特意将封装函数命名为 SealKey,而不是 EncryptMessage,避免调用方把它当成通用加密器。标准库 Encapsulate 返回 sharedKey、ciphertext,本文函数则返回 ciphertext、secret、error,因此中间使用具名局部变量,避免反向传输秘密。PublicKey 中的导出方法也不能与私钥的 Bytes 混用。

解封装无错误不等于身份可信

Decapsulate 对长度错误返回 error,但长度正确而无效的密文可能不报错,而是得到与发送侧不同的密钥。这是文档明示的行为,不能把 err == nil 当成密文完整性或发送者身份已经得到确认。公开密钥解析成功,同样只说明编码有效,不说明它属于期望的接收者。

在这份教学封装里,NewReceiver 处理生成错误,SealKey 处理公钥解析错误,OpenKey 处理解封装错误,demo 只比较本地两端结果。应用协议的认证与确认不在这几个函数内;实际系统应使用经过审查的认证协议,不应把这个示例直接当作生产握手替代品。

三个封装函数与输入错误及认证边界的关系
图2:原创静态契约图。原语调用和协议边界分别分组,强调错误处理与身份认证是不同职责;不是测试输出或协议时序图。

迁移时先固定参数与职责

迁移的第一步不是替换所有旧密码接口,而是确定两端都支持同一参数集和编码,并让公开材料与秘密材料在应用接口上分开。本文不讨论业务密钥派生、混合握手、会话恢复或消息加密,也不提供未经审查的自定义协议方案。

  • 工具链应支持 crypto/mlkem,部署版本与双方协议约定一致。
  • 私钥由接收侧保管,不因调试方便导出到请求体。
  • 共享秘密不进入日志、示例输出或监控标签。
  • 接口错误直接返回;不在出错时悄悄使用固定值或随机替代值继续。
  • 示例两端相等只说明本次内部配对,不等于完成身份认证或互操作认证。

封装密文里是不是业务内容?

不是。它服务于共享秘密的恢复,本文没有传入任何业务明文。

重复封装同一公钥会得到相同结果吗?

不要把封装当作确定性转换。示例依赖标准库随机封装接口,不能通过固定输出字符串判断它是否正确。

为什么没有打印共享秘密供对照?

展示秘密不是理解流程的必要条件。教学比较放在同一进程内;跨端如何认证、确认和使用结果,必须由完整协议负责。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go runtime.AddCleanup 怎样注册对象清理回调Go runtime.AddCleanup 怎样注册对象清理回调
上一篇
Go runtime.AddCleanup 怎样注册对象清理回调
Go cmp.Or 怎样按优先级选择非零配置值
下一篇
Go cmp.Or 怎样按优先级选择非零配置值
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    556次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    606次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    632次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    588次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    413次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码