wycheproof
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWycheproof
Wycheproof
Wycheproof is an extensive collection of test vectors designed to verify the correctness of cryptographic implementations and test against known attacks. Originally developed by Google, it is now a community-managed project where contributors can add test vectors for specific cryptographic constructions.
Wycheproof 是一个广泛的测试向量集合,旨在验证密码学实现的正确性,并针对已知攻击进行测试。它最初由 Google 开发,现在是一个社区管理的项目,贡献者可以为特定的密码学结构添加测试向量。
Background
背景
Key Concepts
核心概念
| Concept | Description |
|---|---|
| Test vector | Input/output pair for validating crypto implementation correctness |
| Test group | Collection of test vectors sharing attributes (key size, IV size, curve) |
| Result flag | Indicates if test should pass (valid), fail (invalid), or is acceptable |
| Edge case testing | Testing for known vulnerabilities and attack patterns |
| 概念 | 描述 |
|---|---|
| 测试向量 | 用于验证密码学实现正确性的输入/输出对 |
| 测试组 | 共享属性(密钥大小、IV大小、曲线)的测试向量集合 |
| 结果标志 | 指示测试应通过(有效)、失败(无效)还是可接受 |
| 边缘情况测试 | 针对已知漏洞和攻击模式进行测试 |
Why This Matters
重要性
Cryptographic implementations are notoriously difficult to get right. Even small bugs can:
- Expose private keys
- Allow signature forgery
- Enable message decryption
- Create consensus problems when different implementations accept/reject the same inputs
Wycheproof has found vulnerabilities in major libraries including OpenJDK's SHA1withDSA, Bouncy Castle's ECDHC, and the elliptic npm package.
密码学实现向来难以做到完全正确。即使是微小的漏洞也可能:
- 暴露私钥
- 允许签名伪造
- 启用消息解密
- 当不同实现对同一输入的接受/拒绝情况不同时,引发一致性问题
Wycheproof 已在多个主流库中发现漏洞,包括 OpenJDK 的 SHA1withDSA、Bouncy Castle 的 ECDHC 以及 elliptic npm 包。
When to Use
使用场景
Apply Wycheproof when:
- Testing cryptographic implementations (AES-GCM, ECDSA, ECDH, RSA, etc.)
- Validating that crypto code handles edge cases correctly
- Verifying implementations against known attack vectors
- Setting up CI/CD for cryptographic libraries
- Auditing third-party crypto code for correctness
Consider alternatives when:
- Testing for timing side-channels (use constant-time testing tools instead)
- Finding new unknown bugs (use fuzzing instead)
- Testing custom/experimental cryptographic algorithms (Wycheproof only covers established algorithms)
在以下场景使用 Wycheproof:
- 测试密码学实现(AES-GCM、ECDSA、ECDH、RSA 等)
- 验证密码代码能否正确处理边缘情况
- 针对已知攻击向量验证实现
- 为密码学库设置 CI/CD
- 审计第三方密码代码的正确性
在以下场景考虑替代方案:
- 测试计时侧信道(改用恒定时间测试工具)
- 发现新的未知漏洞(改用模糊测试)
- 测试自定义/实验性密码学算法(Wycheproof 仅覆盖已确立的算法)
Quick Reference
快速参考
| Scenario | Recommended Approach | Notes |
|---|---|---|
| AES-GCM implementation | Use | 316 test vectors across 44 test groups |
| ECDSA verification | Use | Tests signature malleability, DER encoding |
| ECDH key exchange | Use | Tests invalid curve attacks |
| RSA signatures | Use | Tests padding oracle attacks |
| ChaCha20-Poly1305 | Use | Tests AEAD implementation |
| 场景 | 推荐方法 | 说明 |
|---|---|---|
| AES-GCM 实现 | 使用 | 44 个测试组,共 316 个测试向量 |
| ECDSA 验证 | 针对特定曲线使用 | 测试签名可塑性、DER 编码 |
| ECDH 密钥交换 | 使用 | 测试无效曲线攻击 |
| RSA 签名 | 使用 | 测试填充 oracle 攻击 |
| ChaCha20-Poly1305 | 使用 | 测试 AEAD 实现 |
Testing Workflow
测试工作流
Phase 1: Setup Phase 2: Parse Test Vectors
┌─────────────────┐ ┌─────────────────┐
│ Add Wycheproof │ → │ Load JSON file │
│ as submodule │ │ Filter by params│
└─────────────────┘ └─────────────────┘
↓ ↓
Phase 4: CI Integration Phase 3: Write Harness
┌─────────────────┐ ┌─────────────────┐
│ Auto-update │ ← │ Test valid & │
│ test vectors │ │ invalid cases │
└─────────────────┘ └─────────────────┘Phase 1: Setup Phase 2: Parse Test Vectors
┌─────────────────┐ ┌─────────────────┐
│ Add Wycheproof │ → │ Load JSON file │
│ as submodule │ │ Filter by params│
└─────────────────┘ └─────────────────┘
↓ ↓
Phase 4: CI Integration Phase 3: Write Harness
┌─────────────────┐ ┌─────────────────┐
│ Auto-update │ ← │ Test valid & │
│ test vectors │ │ invalid cases │
└─────────────────┘ └─────────────────┘Repository Structure
仓库结构
The Wycheproof repository is organized as follows:
text
┣ 📜 README.md : Project overview
┣ 📂 doc : Documentation
┣ 📂 java : Java JCE interface testing harness
┣ 📂 javascript : JavaScript testing harness
┣ 📂 schemas : Test vector schemas
┣ 📂 testvectors : Test vectors
┗ 📂 testvectors_v1 : Updated test vectors (more detailed)The essential folders are and . While both contain similar files, includes more detailed information and is recommended for new integrations.
testvectorstestvectors_v1testvectors_v1Wycheproof 仓库的组织结构如下:
text
┣ 📜 README.md : 项目概述
┣ 📂 doc : 文档
┣ 📂 java : Java JCE 接口测试工具
┣ 📂 javascript : JavaScript 测试工具
┣ 📂 schemas : 测试向量 schema
┣ 📂 testvectors : 测试向量
┗ 📂 testvectors_v1 : 更新后的测试向量(更详细)核心文件夹是 和 。虽然两者包含相似的文件,但 包含更详细的信息,推荐用于新集成。
testvectorstestvectors_v1testvectors_v1Supported Algorithms
支持的算法
Wycheproof provides test vectors for a wide range of cryptographic algorithms:
| Category | Algorithms |
|---|---|
| Symmetric Encryption | AES-GCM, AES-EAX, ChaCha20-Poly1305 |
| Signatures | ECDSA, EdDSA, RSA-PSS, RSA-PKCS1 |
| Key Exchange | ECDH, X25519, X448 |
| Hashing | HMAC, HKDF |
| Curves | secp256k1, secp256r1, secp384r1, secp521r1, ed25519, ed448 |
Wycheproof 为多种密码学算法提供测试向量:
| 类别 | 算法 |
|---|---|
| 对称加密 | AES-GCM, AES-EAX, ChaCha20-Poly1305 |
| 签名 | ECDSA, EdDSA, RSA-PSS, RSA-PKCS1 |
| 密钥交换 | ECDH, X25519, X448 |
| 哈希 | HMAC, HKDF |
| 曲线 | secp256k1, secp256r1, secp384r1, secp521r1, ed25519, ed448 |
Test File Structure
测试文件结构
Each JSON test file tests a specific cryptographic construction. All test files share common attributes:
json
"algorithm" : The name of the algorithm tested
"schema" : The JSON schema (found in schemas folder)
"generatorVersion" : The version number
"numberOfTests" : The total number of test vectors in this file
"header" : Detailed description of test vectors
"notes" : In-depth explanation of flags in test vectors
"testGroups" : Array of one or multiple test groups每个 JSON 测试文件针对特定的密码学结构。所有测试文件共享以下通用属性:
json
"algorithm" : 测试的算法名称
"schema" : JSON schema(位于 schemas 文件夹)
"generatorVersion" : 版本号
"numberOfTests" : 此文件中的测试向量总数
"header" : 测试向量的详细描述
"notes" : 测试向量中标志的深入解释
"testGroups" : 一个或多个测试组的数组Test Groups
测试组
Test groups group sets of tests based on shared attributes such as:
- Key sizes
- IV sizes
- Public keys
- Curves
This classification allows extracting tests that meet specific criteria relevant to the construction being tested.
测试组基于共享属性对测试进行分组,例如:
- 密钥大小
- IV 大小
- 公钥
- 曲线
这种分类允许提取与正在测试的结构相关的特定测试用例。
Test Vector Attributes
测试向量属性
Shared Attributes
共享属性
All test vectors contain four common fields:
- tcId: Unique identifier for the test vector within a file
- comment: Additional information about the test case
- flags: Descriptions of specific test case types and potential dangers (referenced in field)
notes - result: Expected outcome of the test
The field can take three values:
result| Result | Meaning |
|---|---|
| valid | Test case should succeed |
| acceptable | Test case is allowed to succeed but contains non-ideal attributes |
| invalid | Test case should fail |
所有测试向量包含四个通用字段:
- tcId: 文件内测试向量的唯一标识符
- comment: 测试用例的附加信息
- flags: 特定测试用例类型和潜在风险的描述(参考 字段)
notes - result: 测试的预期结果
result| 结果 | 含义 |
|---|---|
| valid | 测试用例应通过 |
| acceptable | 测试用例可通过,但包含非理想属性 |
| invalid | 测试用例应失败 |
Unique Attributes
独有属性
Unique attributes are specific to the algorithm being tested:
| Algorithm | Unique Attributes |
|---|---|
| AES-GCM | |
| ECDH secp256k1 | |
| ECDSA | |
| EdDSA | |
独有属性特定于所测试的算法:
| 算法 | 独有属性 |
|---|---|
| AES-GCM | |
| ECDH secp256k1 | |
| ECDSA | |
| EdDSA | |
Implementation Guide
实现指南
Phase 1: Add Wycheproof to Your Project
阶段 1:将 Wycheproof 添加到项目中
Option 1: Git Submodule (Recommended)
Adding Wycheproof as a git submodule ensures automatic updates:
bash
git submodule add https://github.com/C2SP/wycheproof.gitOption 2: Fetch Specific Test Vectors
If submodules aren't possible, fetch specific JSON files:
bash
#!/bin/bash
TMP_WYCHEPROOF_FOLDER=".wycheproof/"
TEST_VECTORS=('aes_gcm_test.json' 'aes_eax_test.json')
BASE_URL="https://raw.githubusercontent.com/C2SP/wycheproof/master/testvectors_v1/"选项 1:Git 子模块(推荐)
将 Wycheproof 添加为 Git 子模块可确保自动更新:
bash
git submodule add https://github.com/C2SP/wycheproof.git选项 2:获取特定测试向量
如果无法使用子模块,可以获取特定的 JSON 文件:
bash
#!/bin/bash
TMP_WYCHEPROOF_FOLDER=".wycheproof/"
TEST_VECTORS=('aes_gcm_test.json' 'aes_eax_test.json')
BASE_URL="https://raw.githubusercontent.com/C2SP/wycheproof/master/testvectors_v1/"Create wycheproof folder
Create wycheproof folder
mkdir -p $TMP_WYCHEPROOF_FOLDER
mkdir -p $TMP_WYCHEPROOF_FOLDER
Request all test vector files if they don't exist
Request all test vector files if they don't exist
for i in "${TEST_VECTORS[@]}"; do
if [ ! -f "${TMP_WYCHEPROOF_FOLDER}${i}" ]; then
curl -o "${TMP_WYCHEPROOF_FOLDER}${i}" "${BASE_URL}${i}"
if [ $? -ne 0 ]; then
echo "Failed to download ${i}"
exit 1
fi
fi
done
undefinedfor i in "${TEST_VECTORS[@]}"; do
if [ ! -f "${TMP_WYCHEPROOF_FOLDER}${i}" ]; then
curl -o "${TMP_WYCHEPROOF_FOLDER}${i}" "${BASE_URL}${i}"
if [ $? -ne 0 ]; then
echo "Failed to download ${i}"
exit 1
fi
fi
done
undefinedPhase 2: Parse Test Vectors
阶段 2:解析测试向量
Identify the test file for your algorithm and parse the JSON:
Python Example:
python
import json
def load_wycheproof_test_vectors(path: str):
testVectors = []
try:
with open(path, "r") as f:
wycheproof_json = json.loads(f.read())
except FileNotFoundError:
print(f"No Wycheproof file found at: {path}")
return testVectors
# Attributes that need hex-to-bytes conversion
convert_attr = {"key", "aad", "iv", "msg", "ct", "tag"}
for testGroup in wycheproof_json["testGroups"]:
# Filter test groups based on implementation constraints
if testGroup["ivSize"] < 64 or testGroup["ivSize"] > 1024:
continue
for tv in testGroup["tests"]:
# Convert hex strings to bytes
for attr in convert_attr:
if attr in tv:
tv[attr] = bytes.fromhex(tv[attr])
testVectors.append(tv)
return testVectorsJavaScript Example:
javascript
const fs = require('fs').promises;
async function loadWycheproofTestVectors(path) {
const tests = [];
try {
const fileContent = await fs.readFile(path);
const data = JSON.parse(fileContent.toString());
data.testGroups.forEach(testGroup => {
testGroup.tests.forEach(test => {
// Add shared test group properties to each test
test['pk'] = testGroup.publicKey.pk;
tests.push(test);
});
});
} catch (err) {
console.error('Error reading or parsing file:', err);
throw err;
}
return tests;
}确定算法对应的测试文件并解析 JSON:
Python 示例:
python
import json
def load_wycheproof_test_vectors(path: str):
testVectors = []
try:
with open(path, "r") as f:
wycheproof_json = json.loads(f.read())
except FileNotFoundError:
print(f"No Wycheproof file found at: {path}")
return testVectors
# Attributes that need hex-to-bytes conversion
convert_attr = {"key", "aad", "iv", "msg", "ct", "tag"}
for testGroup in wycheproof_json["testGroups"]:
# Filter test groups based on implementation constraints
if testGroup["ivSize"] < 64 or testGroup["ivSize"] > 1024:
continue
for tv in testGroup["tests"]:
# Convert hex strings to bytes
for attr in convert_attr:
if attr in tv:
tv[attr] = bytes.fromhex(tv[attr])
testVectors.append(tv)
return testVectorsJavaScript 示例:
javascript
const fs = require('fs').promises;
async function loadWycheproofTestVectors(path) {
const tests = [];
try {
const fileContent = await fs.readFile(path);
const data = JSON.parse(fileContent.toString());
data.testGroups.forEach(testGroup => {
testGroup.tests.forEach(test => {
// Add shared test group properties to each test
test['pk'] = testGroup.publicKey.pk;
tests.push(test);
});
});
} catch (err) {
console.error('Error reading or parsing file:', err);
throw err;
}
return tests;
}Phase 3: Write Testing Harness
阶段 3:编写测试工具
Create test functions that handle both valid and invalid test cases.
Python/pytest Example:
python
import pytest
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
tvs = load_wycheproof_test_vectors("wycheproof/testvectors_v1/aes_gcm_test.json")
@pytest.mark.parametrize("tv", tvs, ids=[str(tv['tcId']) for tv in tvs])
def test_encryption(tv):
try:
aesgcm = AESGCM(tv['key'])
ct = aesgcm.encrypt(tv['iv'], tv['msg'], tv['aad'])
except ValueError as e:
# Implementation raised error - verify test was expected to fail
assert tv['result'] != 'valid', tv['comment']
return
if tv['result'] == 'valid':
assert ct[:-16] == tv['ct'], f"Ciphertext mismatch: {tv['comment']}"
assert ct[-16:] == tv['tag'], f"Tag mismatch: {tv['comment']}"
elif tv['result'] == 'invalid' or tv['result'] == 'acceptable':
assert ct[:-16] != tv['ct'] or ct[-16:] != tv['tag']
@pytest.mark.parametrize("tv", tvs, ids=[str(tv['tcId']) for tv in tvs])
def test_decryption(tv):
try:
aesgcm = AESGCM(tv['key'])
decrypted_msg = aesgcm.decrypt(tv['iv'], tv['ct'] + tv['tag'], tv['aad'])
except ValueError:
assert tv['result'] != 'valid', tv['comment']
return
except InvalidTag:
assert tv['result'] != 'valid', tv['comment']
assert 'ModifiedTag' in tv['flags'], f"Expected 'ModifiedTag' flag: {tv['comment']}"
return
assert tv['result'] == 'valid', f"No invalid test case should pass: {tv['comment']}"
assert decrypted_msg == tv['msg'], f"Decryption mismatch: {tv['comment']}"JavaScript/Mocha Example:
javascript
const assert = require('assert');
function testFactory(tcId, tests) {
it(`[${tcId + 1}] ${tests[tcId].comment}`, function () {
const test = tests[tcId];
const ed25519 = new eddsa('ed25519');
const key = ed25519.keyFromPublic(toArray(test.pk, 'hex'));
let sig;
if (test.result === 'valid') {
sig = key.verify(test.msg, test.sig);
assert.equal(sig, true, `[${test.tcId}] ${test.comment}`);
} else if (test.result === 'invalid') {
try {
sig = key.verify(test.msg, test.sig);
} catch (err) {
// Point could not be decoded
sig = false;
}
assert.equal(sig, false, `[${test.tcId}] ${test.comment}`);
}
});
}
// Generate tests for all test vectors
for (var tcId = 0; tcId < tests.length; tcId++) {
testFactory(tcId, tests);
}创建处理有效和无效测试用例的测试函数。
Python/pytest 示例:
python
import pytest
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
tvs = load_wycheproof_test_vectors("wycheproof/testvectors_v1/aes_gcm_test.json")
@pytest.mark.parametrize("tv", tvs, ids=[str(tv['tcId']) for tv in tvs])
def test_encryption(tv):
try:
aesgcm = AESGCM(tv['key'])
ct = aesgcm.encrypt(tv['iv'], tv['msg'], tv['aad'])
except ValueError as e:
# Implementation raised error - verify test was expected to fail
assert tv['result'] != 'valid', tv['comment']
return
if tv['result'] == 'valid':
assert ct[:-16] == tv['ct'], f"Ciphertext mismatch: {tv['comment']}"
assert ct[-16:] == tv['tag'], f"Tag mismatch: {tv['comment']}"
elif tv['result'] == 'invalid' or tv['result'] == 'acceptable':
assert ct[:-16] != tv['ct'] or ct[-16:] != tv['tag']
@pytest.mark.parametrize("tv", tvs, ids=[str(tv['tcId']) for tv in tvs])
def test_decryption(tv):
try:
aesgcm = AESGCM(tv['key'])
decrypted_msg = aesgcm.decrypt(tv['iv'], tv['ct'] + tv['tag'], tv['aad'])
except ValueError:
assert tv['result'] != 'valid', tv['comment']
return
except InvalidTag:
assert tv['result'] != 'valid', tv['comment']
assert 'ModifiedTag' in tv['flags'], f"Expected 'ModifiedTag' flag: {tv['comment']}"
return
assert tv['result'] == 'valid', f"No invalid test case should pass: {tv['comment']}"
assert decrypted_msg == tv['msg'], f"Decryption mismatch: {tv['comment']}"JavaScript/Mocha 示例:
javascript
const assert = require('assert');
function testFactory(tcId, tests) {
it(`[${tcId + 1}] ${tests[tcId].comment}`, function () {
const test = tests[tcId];
const ed25519 = new eddsa('ed25519');
const key = ed25519.keyFromPublic(toArray(test.pk, 'hex'));
let sig;
if (test.result === 'valid') {
sig = key.verify(test.msg, test.sig);
assert.equal(sig, true, `[${test.tcId}] ${test.comment}`);
} else if (test.result === 'invalid') {
try {
sig = key.verify(test.msg, test.sig);
} catch (err) {
// Point could not be decoded
sig = false;
}
assert.equal(sig, false, `[${test.tcId}] ${test.comment}`);
}
});
}
// Generate tests for all test vectors
for (var tcId = 0; tcId < tests.length; tcId++) {
testFactory(tcId, tests);
}Phase 4: CI Integration
阶段 4:CI 集成
Ensure test vectors stay up to date by:
- Using git submodules: Update submodule in CI before running tests
- Fetching latest vectors: Run fetch script before test execution
- Scheduled updates: Set up weekly/monthly updates to catch new test vectors
通过以下方式确保测试向量保持最新:
- 使用 Git 子模块:在运行测试前在 CI 中更新子模块
- 获取最新向量:在测试执行前运行获取脚本
- 定期更新:设置每周/每月更新以获取新的测试向量
Common Vulnerabilities Detected
常见检测到的漏洞
Wycheproof test vectors are designed to catch specific vulnerability patterns:
| Vulnerability | Description | Affected Algorithms | Example CVE |
|---|---|---|---|
| Signature malleability | Multiple valid signatures for same message | ECDSA, EdDSA | CVE-2024-42459 |
| Invalid DER encoding | Accepting non-canonical DER signatures | ECDSA | CVE-2024-42460, CVE-2024-42461 |
| Invalid curve attacks | ECDH with invalid curve points | ECDH | Common in many libraries |
| Padding oracle | Timing leaks in padding validation | RSA-PKCS1 | Historical OpenSSL issues |
| Tag forgery | Accepting modified authentication tags | AES-GCM, ChaCha20-Poly1305 | Various implementations |
Wycheproof 测试向量旨在检测特定的漏洞模式:
| 漏洞 | 描述 | 受影响算法 | 示例 CVE |
|---|---|---|---|
| 签名可塑性 | 同一消息存在多个有效签名 | ECDSA, EdDSA | CVE-2024-42459 |
| 无效 DER 编码 | 接受非规范 DER 签名 | ECDSA | CVE-2024-42460, CVE-2024-42461 |
| 无效曲线攻击 | 使用无效曲线点的 ECDH | ECDH | 多个库中常见 |
| 填充 Oracle | 填充验证中的计时泄露 | RSA-PKCS1 | 历史 OpenSSL 问题 |
| 标签伪造 | 接受修改后的认证标签 | AES-GCM, ChaCha20-Poly1305 | 多种实现 |
Signature Malleability: Deep Dive
签名可塑性:深入分析
Problem: Implementations that don't validate signature encoding can accept multiple valid signatures for the same message.
Example (EdDSA): Appending or removing zeros from signature:
text
Valid signature: ...6a5c51eb6f946b30d
Invalid signature: ...6a5c51eb6f946b30d0000 (should be rejected)How to detect:
python
undefined问题: 未验证签名编码的实现可能接受同一消息的多个有效签名。
示例(EdDSA): 在签名后附加或移除零:
text
Valid signature: ...6a5c51eb6f946b30d
Invalid signature: ...6a5c51eb6f946b30d0000 (应被拒绝)检测方法:
python
undefinedAdd signature length check
添加签名长度检查
if len(sig) != 128: # EdDSA signatures must be exactly 64 bytes (128 hex chars)
return False
**Impact:** Can lead to consensus problems when different implementations accept/reject the same signatures.
**Related Wycheproof tests:**
- EdDSA: tcId 37 - "removing 0 byte from signature"
- ECDSA: tcId 06 - "Legacy: ASN encoding of r misses leading 0"if len(sig) != 128: # EdDSA 签名必须恰好为 64 字节(128 个十六进制字符)
return False
**影响:** 当不同实现对同一签名的接受/拒绝情况不同时,会引发一致性问题。
**相关 Wycheproof 测试:**
- EdDSA: tcId 37 - "removing 0 byte from signature"
- ECDSA: tcId 06 - "Legacy: ASN encoding of r misses leading 0"Case Study: Elliptic npm Package
案例研究:elliptic npm 包
This case study demonstrates how Wycheproof found three CVEs in the popular elliptic npm package (3000+ dependents, millions of weekly downloads).
本案例研究展示了 Wycheproof 如何在流行的 elliptic npm 包(3000+ 依赖项,数百万周下载量)中发现三个 CVE。
Overview
概述
The elliptic library is an elliptic-curve cryptography library written in JavaScript, supporting ECDH, ECDSA, and EdDSA. Using Wycheproof test vectors on version 6.5.6 revealed multiple vulnerabilities:
- CVE-2024-42459: EdDSA signature malleability (appending/removing zeros)
- CVE-2024-42460: ECDSA DER encoding - invalid bit placement
- CVE-2024-42461: ECDSA DER encoding - leading zero in length field
elliptic 库是一个用 JavaScript 编写的椭圆曲线密码学库,支持 ECDH、ECDSA 和 EdDSA。在版本 6.5.6 上使用 Wycheproof 测试向量发现了多个漏洞:
- CVE-2024-42459: EdDSA 签名可塑性(附加/移除零)
- CVE-2024-42460: ECDSA DER 编码 - 无效位放置
- CVE-2024-42461: ECDSA DER 编码 - 长度字段前导零
Methodology
方法
- Identify supported curves: ed25519 for EdDSA
- Find test vectors:
testvectors_v1/ed25519_test.json - Parse test vectors: Load JSON and extract tests
- Write test harness: Create parameterized tests
- Run tests: Identify failures
- Analyze root causes: Examine implementation code
- Propose fixes: Add validation checks
- 确定支持的曲线:EdDSA 使用 ed25519
- 查找测试向量:
testvectors_v1/ed25519_test.json - 解析测试向量:加载 JSON 并提取测试用例
- 编写测试工具:创建参数化测试
- 运行测试:识别失败用例
- 分析根本原因:检查实现代码
- 提出修复方案:添加验证检查
Key Findings
关键发现
EdDSA Issue (CVE-2024-42459):
- Missing signature length validation
- Allowed trailing zeros in signatures
- Fix: Add
if(sig.length !== 128) return false;
ECDSA Issue 1 (CVE-2024-42460):
- Missing check for first bit being zero in DER-encoded r and s values
- Fix: Add
if ((data[p.place] & 128) !== 0) return false;
ECDSA Issue 2 (CVE-2024-42461):
- DER length field accepted leading zeros
- Fix: Add
if(buf[p.place] === 0x00) return false;
EdDSA 问题(CVE-2024-42459):
- 缺少签名长度验证
- 允许签名末尾有尾随零
- 修复:添加
if(sig.length !== 128) return false;
ECDSA 问题 1(CVE-2024-42460):
- 缺少对 DER 编码的 r 和 s 值首位为零的检查
- 修复:添加
if ((data[p.place] & 128) !== 0) return false;
ECDSA 问题 2(CVE-2024-42461):
- DER 长度字段接受前导零
- 修复:添加
if(buf[p.place] === 0x00) return false;
Impact
影响
All three vulnerabilities allowed multiple valid signatures for a single message, leading to consensus problems across implementations.
Lessons learned:
- Wycheproof catches subtle encoding bugs
- Reusable test harnesses pay dividends
- Test vector comments and flags help diagnose issues
- Even popular libraries benefit from systematic test vector validation
这三个漏洞都允许同一消息存在多个有效签名,导致不同实现之间的一致性问题。
经验教训:
- Wycheproof 能捕获细微的编码漏洞
- 可重用的测试工具会带来长期收益
- 测试向量的注释和标志有助于诊断问题
- 即使是流行库也能从系统的测试向量验证中受益
Advanced Usage
高级用法
Tips and Tricks
技巧和窍门
| Tip | Why It Helps |
|---|---|
| Filter test groups by parameters | Focus on test vectors relevant to your implementation constraints |
| Use test vector flags | Understand specific vulnerability patterns being tested |
Check the | Get detailed explanations of flag meanings |
| Test both encrypt/decrypt and sign/verify | Ensure bidirectional correctness |
| Run tests in CI | Catch regressions and benefit from new test vectors |
| Use parameterized tests | Get clear failure messages with tcId and comment |
| 技巧 | 优势 |
|---|---|
| 按参数过滤测试组 | 专注于与实现约束相关的测试向量 |
| 使用测试向量标志 | 了解正在测试的特定漏洞模式 |
查看 | 获取标志含义的详细解释 |
| 同时测试加密/解密和签名/验证 | 确保双向正确性 |
| 在 CI 中运行测试 | 捕获回归问题并受益于新测试向量 |
| 使用参数化测试 | 获取包含 tcId 和注释的清晰失败消息 |
Common Mistakes
常见错误
| Mistake | Why It's Wrong | Correct Approach |
|---|---|---|
| Only testing valid cases | Misses vulnerabilities where invalid inputs are accepted | Test all result types: valid, invalid, acceptable |
| Ignoring "acceptable" result | Implementation might have subtle bugs | Treat acceptable as warnings worth investigating |
| Not filtering test groups | Wastes time on unsupported parameters | Filter by keySize, ivSize, etc. based on your implementation |
| Not updating test vectors | Miss new vulnerability patterns | Use submodules or scheduled fetches |
| Testing only one direction | Encrypt/sign might work but decrypt/verify fails | Test both operations |
| 错误 | 原因 | 正确做法 |
|---|---|---|
| 仅测试有效用例 | 遗漏接受无效输入的漏洞 | 测试所有结果类型:有效、无效、可接受 |
| 忽略 "acceptable" 结果 | 实现可能存在细微漏洞 | 将可接受结果视为值得调查的警告 |
| 不过滤测试组 | 在不支持的参数上浪费时间 | 根据实现过滤 keySize、ivSize 等 |
| 不更新测试向量 | 遗漏新的漏洞模式 | 使用子模块或定期获取 |
| 仅测试单向操作 | 加密/签名正常但解密/验证失败 | 测试双向操作 |
Related Skills
相关技能
Tool Skills
工具技能
| Skill | Primary Use in Wycheproof Testing |
|---|---|
| pytest | Python testing framework for parameterized tests |
| mocha | JavaScript testing framework for test generation |
| constant-time-testing | Complement Wycheproof with timing side-channel testing |
| cryptofuzz | Fuzz-based crypto testing to find additional bugs |
| 技能 | 在 Wycheproof 测试中的主要用途 |
|---|---|
| pytest | 用于参数化测试的 Python 测试框架 |
| mocha | 用于测试生成的 JavaScript 测试框架 |
| constant-time-testing | 补充 Wycheproof 进行计时侧信道测试 |
| cryptofuzz | 基于模糊测试的密码学测试,以发现更多漏洞 |
Technique Skills
技术技能
| Skill | When to Apply |
|---|---|
| coverage-analysis | Ensure test vectors cover all code paths in crypto implementation |
| property-based-testing | Test mathematical properties (e.g., encrypt/decrypt round-trip) |
| fuzz-harness-writing | Create harnesses for crypto parsers (complements Wycheproof) |
| 技能 | 应用场景 |
|---|---|
| coverage-analysis | 确保测试向量覆盖密码学实现的所有代码路径 |
| property-based-testing | 测试数学属性(如加密/解密往返) |
| fuzz-harness-writing | 为密码学解析器创建工具(补充 Wycheproof) |
Related Domain Skills
相关领域技能
| Skill | Relationship |
|---|---|
| crypto-testing | Wycheproof is a key tool in comprehensive crypto testing methodology |
| fuzzing | Use fuzzing to find bugs Wycheproof doesn't cover (new edge cases) |
| 技能 | 关系 |
|---|---|
| crypto-testing | Wycheproof 是全面密码学测试方法论中的关键工具 |
| fuzzing | 使用模糊测试发现 Wycheproof 未覆盖的漏洞(新边缘情况) |
Skill Dependency Map
技能依赖图
┌─────────────────────┐
│ wycheproof │
│ (this skill) │
└──────────┬──────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ pytest/mocha │ │ constant-time │ │ cryptofuzz │
│ (test framework)│ │ testing │ │ (fuzzing) │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└───────────────────┼───────────────────┘
│
▼
┌──────────────────────────┐
│ Technique Skills │
│ coverage, harness, PBT │
└──────────────────────────┘ ┌─────────────────────┐
│ wycheproof │
│ (this skill) │
└──────────┬──────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ pytest/mocha │ │ constant-time │ │ cryptofuzz │
│ (test framework)│ │ testing │ │ (fuzzing) │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└───────────────────┼───────────────────┘
│
▼
┌──────────────────────────┐
│ Technique Skills │
│ coverage, harness, PBT │
└──────────────────────────┘Resources
资源
Official Repository
官方仓库
The official repository contains:
- All test vectors in and
testvectors/testvectors_v1/ - JSON schemas in
schemas/ - Reference implementations in Java and JavaScript
- Documentation in
doc/
官方仓库包含:
- 和
testvectors/中的所有测试向量testvectors_v1/ - 中的 JSON schema
schemas/ - Java 和 JavaScript 参考实现
- 中的文档
doc/
Real-World Examples
实际示例
The pycryptodome library integrates Wycheproof test vectors in their test suite, demonstrating best practices for Python crypto implementations.
pycryptodome 库在其测试套件中集成了 Wycheproof 测试向量,展示了 Python 密码学实现的最佳实践。
Community Resources
社区资源
- C2SP Community - Cryptographic specifications and standards community maintaining Wycheproof
- Wycheproof issues tracker - Report bugs in test vectors or suggest new constructions
- C2SP Community - 维护 Wycheproof 的密码学规范和标准社区
- Wycheproof 问题追踪器 - 报告测试向量中的漏洞或建议新结构
Summary
总结
Wycheproof is an essential tool for validating cryptographic implementations against known attack vectors and edge cases. By integrating Wycheproof test vectors into your testing workflow:
- Catch subtle encoding and validation bugs
- Prevent signature malleability issues
- Ensure consistent behavior across implementations
- Benefit from community-contributed test vectors
- Protect against known cryptographic vulnerabilities
The investment in writing a reusable testing harness pays dividends through continuous validation as new test vectors are added to the Wycheproof repository.
Wycheproof 是验证密码学实现针对已知攻击向量和边缘情况的必备工具。通过将 Wycheproof 测试向量集成到测试工作流中:
- 捕获细微的编码和验证漏洞
- 防止签名可塑性问题
- 确保不同实现之间的行为一致
- 受益于社区贡献的测试向量
- 防御已知的密码学漏洞
编写可重用测试工具的投入会随着 Wycheproof 仓库添加新测试向量而持续带来回报。