首页/新闻资讯/正文详情

Go 中的 AES-CBC-Ciphertext Stealing(密文窃取)加解密:aescts 包原理与在 Kerberos 加密链中的实战应用

发布时间:2026/9/23 18:50:58 来源:云帆数科 栏目:资讯中心
Go 中的 AES-CBC-Ciphertext Stealing(密文窃取)加解密:aescts 包原理与在 Kerberos 加密链中的实战应用
网络安全【免费下载链接】sliverAdversary Emulation Framework项目地址https://gitcode.com/gh_mirrors/sl/sliver点击查看免费下载本篇文章以 Sliver 仓库中 vendor 化的gopkg.in/jcmturner/aescts.v1包README.md为核心系统讲解在 Go 中如何使用 AES CBC Ciphertext StealingCTS密文窃取模式对数据进行加密与解密包括包的安装与导入、Encrypt/Decrypt两个核心函数的完整语义、三种明文长度场景下的算法分支以及该包在 Kerberos 5RFC 3962 / RFC 8009AES 加密类型中的真实调用链。读完本文你将理解 CTS 模式为何能免填充、其交换末两块并截断的具体实现并能在自己的 Go 项目中正确使用该包。一、CBC 密文窃取Ciphertext Stealing是什么传统 CBC 模式要求明文长度必须是 16 字节AES 块大小的整数倍否则需要使用 PKCS#7 等填充方案补齐最后一个块。而Ciphertext StealingCTS是一种不用填充即可处理任意长度明文的 CBC 变体它让最后两个块互相借用密文——倒数第二个密文块中截取所需字节补全最后一个块加密完成后交换末两块的位置最后再按原始明文长度截断输出。该包的源码注释明确引用了这一设计见 aescts.go为保持一致性密文窃取总是作用于待加密数据的最后两个块。如果数据长度恰好是块大小的整数倍则等价于普通 CBC 模式再将最后两个密文块交换一次加密输出中倒数第二块即最后一个明文块的加密结果被用作下一次加密的初始向量。这意味着 CTS 模式具有两个关键特性输出密文与明文等长无填充膨胀以及可以自然地传递 next IV 用于连续分片的加密——这两点对 Kerberos 这类需要把加密数据嵌入协议消息的场景至关重要。二、获取与导入 aescts 包原文档给出了最直接的获取方式go get gopkg.in/jcmturner/aescts.v1在 Go Modules 模式下更稳妥的做法是指定版本当前仓库 vendor 的版本为 v1.0.1见 implant/go-mod 第 42 行go get gopkg.in/jcmturner/aescts.v1v1.0.1导入方式同样继承自原文档import gopkg.in/jcmturner/aescts.v1该包只暴露两个公开函数aescts.Encrypt与aescts.Decrypt依赖 Go 标准库crypto/aes与crypto/cipher无任何第三方依赖。三、核心 APIEncrypt 与 DecryptEncrypt加密并返回 next IVfunc Encrypt(key, iv, plaintext []byte) ([]byte, []byte, error)参数与返回值对应 aescts.go 的Encrypt实现项说明keyAES 密钥必须是 16 / 24 / 32 字节对应 AES-128/192/256否则aes.NewCipher返回错误iv初始向量必须是 16 字节函数内部不会修改传入的 ivplaintext明文任意长度含非块整数倍允许为空调用则由内部zeroPad报错返回值 1next IV取自加密输出倒数第二块供后续分片加密接力使用返回值 2密文长度与明文严格一致CTS 无填充膨胀返回值 3错误密钥非法、明文为空等场景返回非 nil从源码看Encrypt内部首先用aes.NewCipher(key)创建分组密码再用cipher.NewCBCEncrypter(block, iv)创建 CBC 加密器随后按明文长度分三种分支处理详见下一节。值得注意的是函数内部对plaintext做了拷贝因此不会破坏调用方的切片。Decrypt逆向恢复明文func Decrypt(key, iv, ciphertext []byte) ([]byte, error)Decrypt的实现aescts.go有几点值得注意先拷贝密文源码注释明确指出即使以值传递切片其底层数组仍可能被修改因此内部先copy一份避免污染调用方数据长度下限校验密文长度小于一个块16 字节直接返回错误Ciphertext is not large enough...整数倍场景只需把末两块交换回来再用标准 CBC 解密单个块恰好 16 字节时无法交换直接按 CBC 解密非整数倍场景需要从倒数第二块密文尾部借出npb BlockSize - len(ct) % BlockSize个字节拼接到最后一块上再依次解密最后按len(ct)截断输出。返回值只有明文与错误长度与原始密文等长。四、三种明文长度场景的算法分支Encrypt依据l : len(plaintext)与aes.BlockSize16的关系走三条路径理解这三条路径是掌握该包行为的关键场景 1明文 ≤ 16 字节单块m, _ zeroPad(m, aes.BlockSize) mode.CryptBlocks(m, m) return m, m, nil先用零填充到 16 字节做一次 CBC 加密返回的密文是 16 字节注意此时输出比明文长这是唯一填充的情形next IV 即该密文本身。场景 2明文长度是块大小的整数倍mode.CryptBlocks(m, m) iv m[len(m)-aes.BlockSize:] rb, _ : swapLastTwoBlocks(m, aes.BlockSize) return iv, rb, nil整段按普通 CBC 加密然后交换最后两个密文块返回的 next IV 是交换前的最后一块密文。场景 3明文长度不是块大小的整数倍真正的 CTS先zeroPad到块大小整数倍再调用tailBlocks拆出前半段 rb / 倒数第二块 pb / 最后一块 lb三部分前半段按 CBC 连续加密并滚动更新 iv随后分别加密 pb 与 lb最后将密文按lb pb顺序拼接交换末两块并按原始明文长度ct[:l]截断。这正是维基百科密文窃取条目所描述的 CBC-CTS 标准做法源码注释中直接引用了该参考见 aescts.go。五、辅助函数tailBlocks、swapLastTwoBlocks、zeroPad包内还有三个未导出的辅助函数共同支撑上述流程aescts.gotailBlocks(b []byte, c int) ([]byte, []byte, []byte, error)把切片拆成剩余部分 / 倒数第二块 / 最后一块三块。最后一块的长度按len(b) % BlockSize计算余数为 0 时整块为 16 字节当数据不超过两个块时返回的rb为 nil。数据不大于一个块时返回错误bytes slice is not larger than one block so cannot tail。swapLastTwoBlocks(b []byte, c int) ([]byte, error)在tailBlocks基础上重排为rb lb pb实现末两块交换。加密整数倍场景与解密交换回来两侧都在使用它。zeroPad(b []byte, m int) ([]byte, error)用零字节把数据补到m的整数倍。块大小参数非法m 0或数据为空时返回错误。注意它与 PKCS#7 填充不同——只是补零因为 CTS 最终会按原始长度截断补零部分不进入最终输出。六、仓库中的实战应用Kerberos AES 加密链这个看似只有两个函数的包在仓库中的实际价值体现在它是Kerberos 5 AES 加密类型的内核。aescts 在 implant/go-mod 中被列为间接依赖indirect由gopkg.in/jcmturner/gokrb5.v7 v7.5.0第 45 行引入并被打包进 Sliver 的 implant 端 vendor 目录。RFC 3962AES-CTS-HMAC-SHA1-96rfc3962/encryption.go 中的EncryptData与DecryptData直接转调 aesctsivz : make([]byte, e.GetCypherBlockBitLength()/8) return aescts.Encrypt(key, ivz, data)这里 IV 是全零的 16 字节ivz。对应的加密类型在 aes128-cts-hmac-sha1-96.go 的文件头注释中列出aes128-cts-hmac-sha1-96etype 17128 位密钥与aes256-cts-hmac-sha1-96etype 18256 位密钥加密/解密函数均为 AES in CBC-CTS mode校验和类型为hmac-sha1-96-aes128/25696 位。EncryptMessage在加密前还会拼接随机 confounder 并通过DeriveKey按 usage 派生会话密钥。RFC 8009AES-CTS-HMAC-SHA2 系列rfc8009/encryption.go 的结构类似区别在于AES256_CTS_HMAC_SHA384_192类型需要 32 字节密钥且完整性哈希按HMAC(Ki, IV | C)方式计算先验密再解密见第 108-118 行注释。两条路径最终都汇聚到同一个aescts.Encrypt/aescts.Decrypt。上层链路implant 的 SSH Kerberos 认证在 Sliver 的 implant 端implant/sliver/shell/ssh/ssh.go 的getClient函数在同时提供krb5conf、keytab、realm时走 Kerberos 认证分支调用github.com/yiya1989/sshkrb5/krb5forssh.NewKrb5InitiatorClient该库导入gokrb5.v7的client、spnego、keytab、messages等包见 sshkrb5 client.go。由此构成的依赖链是implant SSH 命令Kerberos 认证 └─ github.com/yiya1989/sshkrb5SPNEGO/KRB5 客户端 └─ gopkg.in/jcmturner/gokrb5.v7RFC 3962 / RFC 8009 加密类型 └─ gopkg.in/jcmturner/aescts.v1AES-CBC-CTS 加解密内核也就是说implant 通过 SSH 使用 Kerberos 票据认证时票据与认证器消息中所有 AES 加密数据的机密性保障最终都落在这个约 186 行的 aescts 包上。七、使用注意事项结合源码行为使用该包时建议注意以下几点密钥与 IV 长度必须正确key必须是 16/24/32 字节iv必须是 16 字节否则要么aes.NewCipher返回错误要么在加密过程中产生错误结果Kerberos 场景中 IV 通常取全零向量。务必保存并使用返回的 next IVEncrypt第一个返回值是供后续加密使用的 next IV加密输出倒数第二块。如果要分片加密长消息并保持 CBC 链式依赖必须在下一片加密时传入它而不是沿用原始 iv。密文长度与明文等长除单块场景输出被补齐到 16 字节外CTS 输出长度恒等于明文长度解密方必须知晓这个语义避免把补零字节误当数据。Decrypt 会做长度校验密文不足一个块会直接返回错误整数倍与非整数倍两条解密路径不能互换必须与加密侧保持一致。在 Sliver 中它是间接依赖日常开发一般无需直接调用 aescts它通过 gokrb5 服务于 implant 的 Kerberos/SPNEGO 认证链路如需独立使用参考第二节的go get与import方式即可。结语aescts.v1虽然是一个只有两个公开函数的小型加密包但它以标准库crypto/aes与crypto/cipher为基础完整实现了 CBC 密文窃取模式的免填充加密并在本仓库中承担着 Kerberos 5 AES 加密类型RFC 3962 / RFC 8009的底层加解密职责。理解其单块 / 整数倍 / 非整数倍三分支逻辑与 next IV 语义既能帮助你在自己的 Go 项目中正确引入 CTS 加密也能更深入地读懂 Sliver implant 中 SSH Kerberos 认证这条完整依赖链。赞分享网络安全【免费下载链接】sliverAdversary Emulation Framework项目地址https://gitcode.com/gh_mirrors/sl/sliver点击查看免费下载相关推荐SeaTunnel FieldEncrypt 加密 Transform 插件实战指南AES-GCM/AES-CBC 字段加解密原理与配置SeaTunnel FieldEncrypt 加密 Transform 插件实战指南AES GCM/AES CBC 字段加解密原理与配置 SeaTunnel数据集成ETL大数据批处理流处理变更数据捕获AhabAssistantLimbusCompanyLimbus Company自动化助手终极指南AhabAssistantLimbusCompanyLimbus Company自动化助手终极指南 AhabAssistantLimbusCompany简称桌面应用RPA计算机视觉MicroPython cryptolib 模块实战AES 加密解密ECB / CBC / CTR完整指南MicroPython cryptolib 模块实战AES 加密解密ECB / CBC / CTR完整指南 本指南以 MicroPython 仓库中 do嵌入式语言运行时编程语言解释器编译器物联网系统编程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

图解原理:搞懂我的自我介绍,告别配置环境卡半天
图解原理:搞懂我的自我介绍,告别配置环境卡半天

图解原理:搞懂我的自我介绍,告别配置环境卡半天 配置环境就卡半天,是不是你的日常?别急,今天用图解原理拆解【我的自我介绍】。 很多开发者一上来就写代码,结果 import… · 2026/9/23 18:50:45

搞定你为何这么叼表情包开发,避开高频面试题中的版本升级坑
搞定你为何这么叼表情包开发,避开高频面试题中的版本升级坑

搞定你为何这么叼表情包开发,避开高频面试题中的版本升级坑 版本升级后 API 全变了,这是很多开发者在维护老旧项目或学习新框架时遇到的最头疼问题。特别是当你在准备高频面试题时,面试官往往喜欢拿这种“看似简单实则陷阱重重”的场景来考察你的底层… · 2026/9/23 18:50:33

LanceDB Node.js 表枚举指南:从弃用的 TableNamesOptions 迁移到 listTables 分页
LanceDB Node.js 表枚举指南:从弃用的 TableNamesOptions 迁移到 listTables 分页

LanceDB Node.js 表枚举指南:从弃用的 TableNamesOptions 迁移到 listTables 分页 【免费下载链接】lancedb Developer-friendly OSS embedded retrieval library for multimodal AI. Search More; Manage Less. 项目地址: https://gitcode.com/gh_mirrors/la/lan… · 2026/9/23 18:50:33

C# Math函数深度解析:精度陷阱、边界条件与高效实践
C# Math函数深度解析:精度陷阱、边界条件与高效实践

做C#开发这些年,Math类是那种看起来简单、用起来也简单,但真往深了挖全是坑的类型。很多人都觉得Math函数不就是Abs、Floor、Round这些吗,查个文档就完事了,但实际在项目里跑起来,精度问题、边界条件、性能损耗全冒出来… · 2026/9/23 19:22:45

自动驾驶多类别交通物体检测数据集:28类标注与YOLO训练实战
自动驾驶多类别交通物体检测数据集:28类标注与YOLO训练实战

简介:这份自动驾驶多类别交通物体检测数据集面向从事目标检测算法研发的工程师、学生与科研人员,尤其适合使用YOLO系列(含YOLOv12)进行模型训练与验证的场景。数据集覆盖28类交通与道路相关目标,从行人、车辆、交通灯到… · 2026/9/23 19:22:45

Python岩石裂缝CT岩心语义分割源码与数据集:U-Net实战
Python岩石裂缝CT岩心语义分割源码与数据集:U-Net实战

简介:这份资源面向计算机视觉与地质工程方向的本科生、研究生及课程设计开发者,提供一套基于Python的CT岩芯与岩石裂缝语义分割完整方案,可用于期末大作业、课程设计或相关课题的快速复现与二次开发。压缩包共15个文件,约1.15MB&a… · 2026/9/23 19:22:45

摩尔投票法原理与高性能优化实践
摩尔投票法原理与高性能优化实践

1. 摩尔投票法基础原理摩尔投票法(Moore Voting Algorithm)是一种用于在数据流或数组中高效寻找多数元素的算法。我第一次接触这个算法是在处理一个实时日志分析系统时,需要快速识别出高频出现的错误类型。1.1 算法核心思想摩尔投票法的精妙之… · 2026/9/23 19:22:45

TensorRT-LLM部署Qwen1.5:从权重转换到引擎构建的完整指南
TensorRT-LLM部署Qwen1.5:从权重转换到引擎构建的完整指南

简介:面向大模型部署工程师与算法开发者的实战资源,聚焦TensorRT-LLM框架下部署Qwen1.5大语言模型的完整过程,针对推理时延高、显存占用大等常见难题,给出从模型转换到生产级部署的可行方案。压缩包共5个文件,包含4个P… · 2026/9/23 19:22:39

WMS库存查询全解析:从底层逻辑到多仓选型实战
WMS库存查询全解析:从底层逻辑到多仓选型实战

做仓储这行,你会发现所有业务最后都会落到同一个问题:货在哪、有多少、能不能发。不同角色问法不一样,客服问的是“客户下单了,库存够不够”,仓管员问的是“这批货在哪个库位”,老板问的是“整体库存健康吗… · 2026/9/23 19:22:39

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码