Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

3.20 ECC与哈希机制:现代密码学的“双子星“

ECC机制概览

ECC(椭圆曲线密码学)提供比RSA更高效的非对称加密:

ECC机制列表:

密钥生成:
CKM_EC_KEY_PAIR_GEN        EC密钥对生成(通用,通过曲线参数区分ECDSA/ECDH)

签名机制:
CKM_ECDSA                  ECDSA签名
CKM_ECDSA_SHA1             ECDSA + SHA1哈希
CKM_ECDSA_SHA256           ECDSA + SHA256哈希
CKM_ECDSA_SHA384           ECDSA + SHA384哈希
CKM_ECDSA_SHA512           ECDSA + SHA512哈希

密钥协商:
CKM_ECDH1_DERIVE           ECDH密钥派生
CKM_ECDH1_COFACTOR_DERIVE  ECDH cofactor密钥派生
CKM_ECMQV_DERIVE           ECMQV密钥派生

国密ECC(厂商扩展,非PKCS#11 v3.1标准):
CKM_SM2_KEY_PAIR_GEN       SM2密钥对生成
CKM_SM2                    SM2签名/加密
CKM_SM2_SM3                SM2 + SM3签名

注意:SM2、SM3等国密机制是厂商对PKCS#11的扩展,并非OASIS PKCS#11 v3.1标准规范的一部分。具体实现和机制值由各厂商定义。


ECC密钥生成

EC密钥对需要指定曲线参数:

常用椭圆曲线:

NIST曲线:
P-192    (192位,已不推荐)
P-224    (224位,过渡期)
P-256    (256位,最常用)
P-384    (384位,高安全)
P-521    (521位,最高安全)

其他曲线:
Curve25519  (255位,现代推荐)
Brainpool曲线(欧洲推荐)
SM2曲线     (中国标准)

OID编码示例:
P-256:1.2.840.10045.3.1.7
Curve25519:1.3.101.110
/* EC密钥对生成(P-256) */

CK_MECHANISM mechanism = {CKM_EC_KEY_PAIR_GEN, NULL_PTR, 0};

// P-256曲线OID
CK_BYTE ecParams[] = {
    0x06, 0x08,  // OID标签和长度
    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07  // P-256 OID
};

CK_ATTRIBUTE publicKeyTemplate[] = {
    {CKA_EC_PARAMS, ecParams, sizeof(ecParams)},
    {CKA_VERIFY, &true, sizeof(true)}
};

CK_ATTRIBUTE privateKeyTemplate[] = {
    {CKA_SENSITIVE, &true, sizeof(true)},
    {CKA_SIGN, &true, sizeof(true)},
    {CKA_DERIVE, &true, sizeof(true)}  // 支持密钥派生
};

CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
rv = C_GenerateKeyPair(hSession, &mechanism,
                       publicKeyTemplate, 2,
                       privateKeyTemplate, 3,
                       &hPublicKey, &hPrivateKey);

ECC与RSA的安全对比

ECC vs RSA:等效安全强度

RSA密钥长度     ECC密钥长度     安全级别
───────────────────────────────────────
1024位         160位          已不安全
2048位         224-256位      当前标准
3072位         256-384位      高安全
7680位         384-512位      极高安全
15360位        512+位         最高安全

ECC优势:
- 更短的密钥长度
- 更快的计算速度
- 更低的资源消耗
- 更适合嵌入式系统

车载推荐:
- P-256:一般安全场景
- P-384:高安全场景
- Curve25519:现代新系统

ECDSA签名

ECDSA是椭圆曲线数字签名算法:

/* ECDSA-SHA256签名 */

CK_MECHANISM mechanism = {CKM_ECDSA_SHA256, NULL_PTR, 0};
rv = C_SignInit(hSession, &mechanism, hPrivateKey);

CK_BYTE data[] = "Data to sign";
CK_BYTE signature[64];  // P-256签名 = 32+32字节(r+s)
CK_ULONG sigLen = 64;

rv = C_Sign(hSession, data, sizeof(data)-1, signature, &sigLen);

签名结构

ECDSA签名格式:

P-256签名(64字节):
┌──────────────────────────────┐
│ r(32字节)                   │ 签名第一部分
├──────────────────────────────┤
│ s(32字节)                   │ 签名第二部分
└──────────────────────────────┘

特点:
- 签名长度 = 2 * 曲线字段长度
- P-256签名 = 64字节
- P-384签名 = 96字节

ECDSA验证

/* ECDSA-SHA256验证 */

CK_MECHANISM mechanism = {CKM_ECDSA_SHA256, NULL_PTR, 0};
rv = C_VerifyInit(hSession, &mechanism, hPublicKey);

CK_BYTE data[] = "Data to sign";
CK_BYTE signature[64];
CK_ULONG sigLen = 64;

rv = C_Verify(hSession, data, sizeof(data)-1, signature, sigLen);

if (rv == CKR_OK) {
    printf("ECDSA签名验证成功\n");
} else if (rv == CKR_SIGNATURE_INVALID) {
    printf("ECDSA签名验证失败\n");
}

ECDH密钥协商

ECDH用于安全协商共享密钥:

ECDH密钥协商流程:

Alice                           Bob
────────────────────────────────────────
生成EC密钥对                    生成EC密钥对
├─ 私钥A                       ├─ 私钥B
└─ 公钥A                       └─ 公钥B

交换公钥:
←──────── 公钥B ────────→
←──────── 公钥A ────────→

派生共享密钥:
C_DeriveKey(私钥A, 公钥B)   C_DeriveKey(私钥B, 公钥A)
    ↓                           ↓
    共享密钥K ←───相同───→ 共享密钥K
/* ECDH密钥派生 */

CK_ECDH1_DERIVE_PARAMS ecdhParams = {
    .kdf = CKD_NULL,              // 密钥派生函数(可选)
    .ulSharedDataLen = 0,
    .pSharedData = NULL_PTR,
    .ulPublicDataLen = sizeof(bobPublicKey),  // Bob公钥长度
    .pPublicData = bobPublicKey   // Bob的公钥数据
};

CK_MECHANISM mechanism = {
    CKM_ECDH1_DERIVE,
    &ecdhParams,
    sizeof(ecdhParams)
};

CK_ULONG keyLen = 32;  // 派生32字节AES密钥

CK_ATTRIBUTE keyTemplate[] = {
    {CKA_KEY_TYPE, &(CK_KEY_TYPE){CKK_AES}, sizeof(CK_KEY_TYPE)},
    {CKA_VALUE_LEN, &keyLen, sizeof(keyLen)},
    {CKA_SENSITIVE, &true, sizeof(true)}
};

CK_OBJECT_HANDLE hSharedKey;
rv = C_DeriveKey(hSession, &mechanism, hPrivateKeyA,
                 keyTemplate, 3, &hSharedKey);

if (rv == CKR_OK) {
    printf("共享密钥派生成功\n");
    // Alice和Bob派生的密钥相同
}

Curve25519:现代椭圆曲线

Curve25519是现代推荐的椭圆曲线:

Curve25519特点:

安全性:
- 255位,等效于RSA-3072
- 设计安全,避免弱点
- 现代密码学推荐

性能:
- 极快计算速度
- 抗侧信道攻击设计
- 适合嵌入式系统

用途:
- X25519:密钥协商
- Ed25519:签名算法

PKCS#11支持:
CKM_EC_MONTGOMERY_KEY_PAIR_GEN  X25519/X448密钥生成
CKM_ECDH1_DERIVE            密钥协商(通过曲线参数指定)
CKM_EC_EDWARDS_KEY_PAIR_GEN    Ed25519/Ed448密钥生成
CKM_EDDSA                   EdDSA签名

哈希机制概览

哈希机制用于计算数据摘要:

哈希机制列表:

SHA系列:
CKM_SHA_1         SHA-1(160位,已不推荐)
CKM_SHA224        SHA-224(224位)
CKM_SHA256        SHA-256(256位)★最常用
CKM_SHA384        SHA-384(384位)
CKM_SHA512        SHA-512(512位)

SHA-3系列:
CKM_SHA3_224      SHA3-224
CKM_SHA3_256      SHA3-256
CKM_SHA3_384      SHA3-384
CKM_SHA3_512      SHA3-512

其他:
CKM_MD5           MD5(128位,已不安全)
CKM_RIPEMD160     RIPEMD-160

国密:
CKM_SM3           SM3(256位)

SHA-256哈希计算

/* SHA-256哈希 */

CK_MECHANISM mechanism = {CKM_SHA256, NULL_PTR, 0};
rv = C_DigestInit(hSession, &mechanism);

CK_BYTE data[] = "Data to hash";
CK_BYTE digest[32];  // SHA-256输出32字节
CK_ULONG digestLen = 32;

rv = C_Digest(hSession, data, sizeof(data)-1, digest, &digestLen);

if (rv == CKR_OK) {
    printf("SHA-256哈希值:");
    for (int i = 0; i < 32; i++) {
        printf("%02x", digest[i]);
    }
    printf("\n");
}

HMAC机制

HMAC使用密钥进行哈希运算:

HMAC机制列表:

CKM_SHA_1_HMAC    HMAC-SHA1(已不推荐)
CKM_SHA224_HMAC   HMAC-SHA224
CKM_SHA256_HMAC   HMAC-SHA256 ★最常用
CKM_SHA384_HMAC   HMAC-SHA384
CKM_SHA512_HMAC   HMAC-SHA512

CKM_MD5_HMAC      HMAC-MD5(已不安全)

国密:
CKM_SM3_HMAC      HMAC-SM3
/* HMAC-SHA256计算 */

CK_MECHANISM mechanism = {CKM_SHA256_HMAC, NULL_PTR, 0};
rv = C_SignInit(hSession, &mechanism, hHmacKey);

CK_BYTE message[] = "Message to authenticate";
CK_BYTE mac[32];  // HMAC输出=哈希长度
CK_ULONG macLen = 32;

rv = C_Sign(hSession, message, sizeof(message)-1, mac, &macLen);

if (rv == CKR_OK) {
    printf("HMAC-SHA256值:");
    for (int i = 0; i < 32; i++) {
        printf("%02x", mac[i]);
    }
    printf("\n");
}

HMAC验证

/* HMAC验证 */

CK_MECHANISM mechanism = {CKM_SHA256_HMAC, NULL_PTR, 0};
rv = C_VerifyInit(hSession, &mechanism, hHmacKey);

CK_BYTE message[] = "Message to authenticate";
CK_BYTE receivedMac[32];
CK_ULONG macLen = 32;

rv = C_Verify(hSession, message, sizeof(message)-1, receivedMac, macLen);

if (rv == CKR_OK) {
    printf("HMAC验证成功,消息真实\n");
} else if (rv == CKR_SIGNATURE_INVALID) {
    printf("HMAC验证失败,消息可能被篡改\n");
}

HKDF:密钥派生函数

HKDF用于从基密钥派生多个子密钥:

HKDF用途:

密钥分层管理:
┌─────────────────────────────────────┐
│ 主密钥(Master Key)                │
│                                     │
│ HKDF派生:                          │
│ ├─ 加密密钥(encryption key)       │
│ ├─ HMAC密钥(authentication key)   │
│ ├─ 会话密钥(session key)          │
│ └─ IV生成密钥(IV derivation key)  │
└─────────────────────────────────────┘
/* HKDF密钥派生 */

CK_HKDF_PARAMS hkdfParams = {
    TRUE,                       /* bExtract */
    TRUE,                       /* bExpand */
    CKM_SHA256,                 /* prfHashMechanism */
    CKZ_SALT_SPECIFIED,         /* ulSaltType */
    salt, sizeof(salt),         /* pSalt, ulSaltLen */
    CK_INVALID_HANDLE,          /* hSaltKey */
    info, sizeof(info)          /* pInfo, ulInfoLen */
};

CK_MECHANISM mechanism = {
    CKM_HKDF_DERIVE,
    &hkdfParams,
    sizeof(hkdfParams)
};

CK_ULONG keyLen = 32;  // 派生32字节密钥

CK_ATTRIBUTE keyTemplate[] = {
    {CKA_KEY_TYPE, &(CK_KEY_TYPE){CKK_AES}, sizeof(CK_KEY_TYPE)},
    {CKA_VALUE_LEN, &keyLen, sizeof(CK_ULONG)}
};

CK_OBJECT_HANDLE hDerivedKey;
rv = C_DeriveKey(hSession, &mechanism, hMasterKey,
                 keyTemplate, 2, &hDerivedKey);

ECC在车载中的应用

车载ECC应用场景:

V2X安全通信:
┌─────────────────────────────────────┐
│ 发送方                              │
│                                     │
│ message = {位置,速度,...}           │
│ signature = ECDSA-SHA256(message)   │
│                                     │
│ 发送:{message, signature}          │
└─────────────────────────────────────┘
                ↓
┌─────────────────────────────────────┐
│ 接收方                              │
│                                     │
│ ECDSA-SHA256验证签名                │
│ → 消息真实可信                      │
└─────────────────────────────────────┘

TLS密钥协商:
┌─────────────────────────────────────┐
│ TLS 1.3握手                         │
│                                     │
│ 使用ECDHE密钥协商                   │
│ ├─ X25519/P-256                     │
│ ├─ 派生会话密钥                     │
│ └─ 加密通信通道                     │
└─────────────────────────────────────┘

固件签名验证:
┌─────────────────────────────────────┐
│ 安全启动                            │
│                                     │
│ 固件签名 = ECDSA-SHA256             │
│ Boot ROM验证签名                    │
│ → 固件可信                          │
│                                     │
│ ECC比RSA更快                        │
│ 车载启动时间敏感                    │
└─────────────────────────────────────┘

哈希算法选择

哈希算法安全对比:

算法        输出长度    安全性    推荐度
───────────────────────────────────────
MD5         128位       已破解    ❌不推荐
SHA-1       160位       已破解    ❌不推荐
SHA-224     224位       安全      ⚠️可用
SHA-256     256位       安全      ✓推荐
SHA-384     384位       安全      ✓高安全
SHA-512     512位       安全      ✓高安全
SHA3-256    256位       安全      ✓现代
SM3         256位       安全      ✓中国标准

车载推荐:
SHA-256:一般场景,平衡性能和安全
SHA-384:高安全场景
SM3:中国合规要求

小结:ECC与哈希机制要点

核心要点回顾:

1. ECC密钥长度优势
   - P-256等效RSA-2048
   - P-384等效RSA-3072
   - 更短密钥,更快计算

2. ECDSA签名特点
   - 签名长度 = 2 * 曲线字段长度
   - P-256签名 = 64字节
   - 比RSA签名更短

3. ECDH密钥协商
   - 双方交换公钥
   - 派生相同共享密钥
   - TLS/V2X常用

4. HMAC认证机制
   - 使用密钥的哈希
   - 验证消息真实性
   - 比签名更高效

5. HKDF密钥派生
   - 从主密钥派生子密钥
   - 密钥分层管理
   - 灵活且安全

6. 哈希算法选择
   - 避免MD5、SHA-1
   - 推荐SHA-256
   - 高安全选SHA-384

ECC和哈希机制是现代密码学的核心,为车载安全提供高效、可靠的密码服务。 下一节,我们将综合实践——看安全属性的合理组合。

【下集预告】

最高安全密钥怎么配置?

可备份密钥怎么配置?

密钥包装怎么实现?

下一节,安全属性组合实战。