偵測加密程式碼中的時間旁路漏洞。在實作或審查加密程式碼、遇到對機密值進行除法、依賴機密的分支,或有關常數時間程式設計的問題時使用,支援 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 <source_file>
# 包含條件分支警告
uv run {baseDir}/ct_analyzer/analyzer.py --warnings <source_file>
# 過濾特定函式
uv run {baseDir}/ct_analyzer/analyzer.py --func 'sign|verify' <source_file>
# JSON 輸出,適合 CI
uv run {baseDir}/ct_analyzer/analyzer.py --json <source_file>
僅限原生編譯語言(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 | JDK,PATH 中有 javac 和 javap |
| Kotlin | Kotlin 編譯器(kotlinc)+ JDK(PATH 中有 javap) |
| 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 | 使用加密安全隨機數產生器 |
| 以機密為索引的查表 | 陣列下標使用機密索引 | 位元切片查表 |
解讀結果
PASSED - 未偵測到可變時間操作。
FAILED - 發現危險指令。範例:
[ERROR] SDIV
Function: decompose_vulnerable
Reason: 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 時間攻擊:早期實作透過除法時間洩漏私鑰位元
參考資料
- Cryptocoding Guidelines - 加密防禦性程式設計
- KyberSlash - 後量子加密中的除法時間
- BearSSL Constant-Time - 實用常數時間技術






