SKILL.md
readonly只读
name
constant-time-analysis
description
检测加密代码中的时序侧信道漏洞。在实现或审查加密代码、遇到对秘密值进行除法运算、秘密相关分支或关于C、C++、Go、Rust、Swift、Java、Kotlin、C#、PHP、JavaScript、TypeScript、Python或Ruby中的常量时间编程问题时使用。
常量时间分析
分析加密代码,检测通过执行时间变化泄露秘密数据的操作。
何时使用
用户编写加密代码? ──是──> 使用此技能
│
否
│
v
用户询问时序攻击? ──是──> 使用此技能
│
否
│
v
代码处理密钥/令牌? ──是──> 使用此技能
│
否
│
v
跳过此技能
具体触发条件:
- 用户实现签名、加密或密钥派生
- 代码包含对秘密派生值使用
/或%运算符 - 用户提及“常量时间”、“时序攻击”、“侧信道”、“KyberSlash”
- 审查名为
sign、verify、encrypt、decrypt、derive_key的函数
何时不使用
- 非加密代码(业务逻辑、UI等)
- 时序泄露无关的公开数据处理
- 不处理秘密、密钥或认证令牌的代码
- 由库处理时序的高级API使用
语言选择
根据文件扩展名或语言上下文,参考相应指南:
| 语言 | 文件扩展名 | 指南 |
|---|---|---|
| C, C++ | .c, .h, .cpp, .cc, .hpp |
references/compiled.md |
| Go | .go |
references/compiled.md |
| Rust | .rs |
references/compiled.md |
| Swift | .swift |
references/swift.md |
| Java | .java |
references/vm-compiled.md |
| Kotlin | .kt, .kts |
references/kotlin.md |
| C# | .cs |
references/vm-compiled.md |
| PHP | .php |
references/php.md |
| JavaScript | .js, .mjs, .cjs |
references/javascript.md |
| TypeScript | .ts, .tsx |
references/javascript.md |
| Python | .py |
references/python.md |
| Ruby | .rb |
references/ruby.md |
快速开始
# 分析任何支持的文件类型
uv run {baseDir}/ct_analyzer/analyzer.py <源文件>
# 包含条件分支警告
uv run {baseDir}/ct_analyzer/analyzer.py --warnings <源文件>
# 过滤特定函数
uv run {baseDir}/ct_analyzer/analyzer.py --func 'sign|verify' <源文件>
# JSON输出用于CI
uv run {baseDir}/ct_analyzer/analyzer.py --json <源文件>
仅限本地编译语言(C, C++, Go, Rust)
# 跨架构测试(推荐)
uv run {baseDir}/ct_analyzer/analyzer.py --arch x86_64 crypto.c
uv run {baseDir}/ct_analyzer/analyzer.py --arch arm64 crypto.c
# 多种优化级别
uv run {baseDir}/ct_analyzer/analyzer.py --opt-level O0 crypto.c
uv run {baseDir}/ct_analyzer/analyzer.py --opt-level O3 crypto.c
VM编译语言(Java, Kotlin, C#)
# 分析Java字节码
uv run {baseDir}/ct_analyzer/analyzer.py CryptoUtils.java
# 分析Kotlin字节码(Android/JVM)
uv run {baseDir}/ct_analyzer/analyzer.py CryptoUtils.kt
# 分析C# IL
uv run {baseDir}/ct_analyzer/analyzer.py CryptoUtils.cs
注意:Java、Kotlin和C#编译为字节码(JVM/CIL),在带有JIT编译的虚拟机上运行。分析器直接检查字节码,而非JIT编译后的本地代码。--arch 和 --opt-level 标志不适用于这些语言。
Swift(iOS/macOS)
# 分析Swift本地架构
uv run {baseDir}/ct_analyzer/analyzer.py crypto.swift
# 分析特定架构(iOS设备)
uv run {baseDir}/ct_analyzer/analyzer.py --arch arm64 crypto.swift
# 使用不同优化级别分析
uv run {baseDir}/ct_analyzer/analyzer.py --opt-level O0 crypto.swift
注意:Swift编译为本地代码,类似C/C++/Go/Rust,因此使用汇编级分析并支持 --arch 和 --opt-level 标志。
前提条件
| 语言 | 要求 |
|---|---|
| C, C++, Go, Rust | PATH中的编译器(gcc/clang、go、rustc) |
| Swift | Xcode或Swift工具链(PATH中的swiftc) |
| Java | 带有javac和javap的JDK(在PATH中) |
| Kotlin | Kotlin编译器(kotlinc)+ JDK(javap)(在PATH中) |
| C# | .NET SDK + ilspycmd(dotnet tool install -g ilspycmd) |
| PHP | 带有VLD扩展或OPcache的PHP |
| JavaScript/TypeScript | PATH中的Node.js |
| Python | PATH中的Python 3.x |
| Ruby | 支持--dump=insns的Ruby |
macOS用户:Homebrew将Java和.NET安装为“keg-only”。您必须将它们添加到PATH:
# 对于Java(添加到~/.zshrc)
export PATH="/opt/homebrew/opt/openjdk@21/bin:$PATH"
# 对于.NET工具(添加到~/.zshrc)
export PATH="$HOME/.dotnet/tools:$PATH"
有关详细设置说明和故障排除,请参见 references/vm-compiled.md。
快速参考
| 问题 | 检测方式 | 修复方法 |
|---|---|---|
| 对秘密值进行除法 | DIV, IDIV, SDIV, UDIV | Barrett约简或乘以逆元 |
| 对秘密值进行分支 | JE, JNE, BEQ, BNE | 常量时间选择(cmov、位掩码) |
| 秘密比较 | 提前退出的memcmp | 使用crypto/subtle或常量时间比较 |
| 弱随机数生成器 | rand(), mt_rand, Math.random | 使用加密安全随机数生成器 |
| 通过秘密值查表 | 以秘密值为索引的数组下标 | 位切片查找 |
解释结果
通过 - 未检测到可变时间操作。
失败 - 发现危险指令。示例:
[ERROR] SDIV
函数: decompose_vulnerable
原因: SDIV具有提前终止优化;执行时间取决于操作数值
验证结果(避免误报)
关键:并非每个被标记的操作都是漏洞。该工具没有数据流分析——它会标记所有潜在危险的操作,无论它们是否涉及秘密值。
对于每个被标记的违规,询问:此操作的输入是否依赖于秘密数据?
-
识别函数的秘密输入(私钥、明文、签名、令牌)
-
从被标记指令回溯数据流到输入
-
常见误报模式:
// 误报:除法使用公开常量,而非秘密 int num_blocks = data_len / 16; // data_len是长度,而非内容 // 真阳性:除法涉及秘密派生值 int32_t q = secret_coef / GAMMA2; // secret_coef来自私钥 -
为每个被标记项记录你的分析
快速分类问题
| 问题 | 如果是 | 如果否 |
|---|---|---|
| 操作数是编译时常量吗? | 可能是误报 | 继续 |
| 操作数是公开参数(长度、计数)吗? | 可能是误报 | 继续 |
| 操作数来自密钥/明文/秘密吗? | 真阳性 | 可能是误报 |
| 攻击者能影响操作数值吗? | 真阳性 | 可能是误报 |
局限性
-
仅静态分析:分析汇编/字节码,而非运行时行为。无法检测缓存时序或微架构侧信道。
-
无数据流分析:标记所有危险操作,无论它们是否处理秘密。需要人工审查。
-
编译器/运行时差异:不同的编译器、优化级别和运行时版本可能产生不同的输出。
实际影响
- KyberSlash(2023):后量子ML-KEM实现中的除法指令导致密钥恢复
- Lucky Thirteen(2013):CBC填充验证中的时序差异导致明文恢复
- RSA时序攻击:早期实现通过除法时序泄露私钥位
参考
- 加密编码指南 - 加密防御性编码
- KyberSlash - 后量子加密中的除法时序
- BearSSL常量时间 - 实用常量时间技术






