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.17 Mechanism系统:密码算法的“配方库“

Mechanism是什么?

在PKCS#11中,Mechanism(机制)是密码算法的“配方“。

每个Mechanism定义了:

  • 算法类型:RSA签名、AES加密、SHA哈希等
  • 算法参数:密钥长度、IV、盐值等
  • 使用方式:签名、加密、哈希、密钥生成等

Mechanism是PKCS#11“提供机制而非策略“原则的核心体现:标准定义了可用的机制,部署者选择使用哪些机制。


CK_MECHANISM结构

Mechanism用一个结构体表示:

/* CK_MECHANISM结构定义 */

typedef struct CK_MECHANISM {
    CK_MECHANISM_TYPE type;      /* 机制类型(如CKM_RSA_PKCS) */
    CK_VOID_PTR       pParameter; /* 机制参数(如IV、Salt等) */
    CK_ULONG          ulParameterLen; /* 参数长度 */
} CK_MECHANISM;

使用示例

/* 无参数的机制 */

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

/* 有参数的机制 */

CK_RSA_PKCS_PSS_PARAMS pssParams = {
    CKM_SHA256,            /* 哈希算法 */
    CKG_MGF1_SHA256,       /* MGF算法 */
    32                     /* 盐值长度 */
};
CK_MECHANISM mechanism = {CKM_RSA_PKCS_PSS, &pssParams, sizeof(pssParams)};
rv = C_SignInit(hSession, &mechanism, hPrivateKey);

CK_MECHANISM_TYPE:机制的标识符

PKCS#11规范定义了100余种机制类型(规范第6章):

分类概览

机制类型分类:

CKM_RSA_*                RSA相关机制(约15种)
CKM_DSA_*                DSA相关机制(约5种)
CKM_ECDSA_*              ECDSA相关机制(约5种)
CKM_ECDH_*               ECDH相关机制(约5种)
CKM_DH_*                 DH相关机制(约5种)
CKM_AES_*                AES相关机制(约20种)
CKM_DES_*                DES相关机制(约15种)
CKM_SHA*                 SHA哈希机制(约30种)
CKM_HMAC*                HMAC机制(约30种)
CKM_*_KEY_PAIR_GEN       密钥生成机制
CKM_*_KEY_DERIVE         密钥派生机制
CKM_*_WRAP               密钥包装机制

查询支持的机制

应用程序可以查询Token支持的机制:

C_GetMechanismList

CK_RV C_GetMechanismList(CK_SLOT_ID slotID,
                          CK_MECHANISM_TYPE_PTR pMechanismList,
                          CK_ULONG_PTR pulCount);

C_GetMechanismInfo

CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID,
                          CK_MECHANISM_TYPE type,
                          CK_MECHANISM_INFO_PTR pInfo);

/* CK_MECHANISM_INFO结构 */
typedef struct CK_MECHANISM_INFO {
    CK_ULONG ulMinKeySize;  /* 最小密钥长度 */
    CK_ULONG ulMaxKeySize;  /* 最大密钥长度 */
    CK_FLAGS flags;         /* 机制标志 */
} CK_MECHANISM_INFO;

/* flags可能值 */
#define CKF_HW                 0x00000001  /* 硬件实现 */
#define CKF_ENCRYPT            0x00000100  /* 可用于加密 */
#define CKF_DECRYPT            0x00000200  /* 可用于解密 */
#define CKF_DIGEST             0x00000400  /* 可用于哈希 */
#define CKF_SIGN               0x00000800  /* 可用于签名 */
#define CKF_SIGN_RECOVER       0x00001000  /* 可用于可恢复签名 */
#define CKF_VERIFY             0x00002000  /* 可用于验证 */
#define CKF_VERIFY_RECOVER     0x00004000  /* 可用于可恢复验证 */
#define CKF_GENERATE           0x00008000  /* 可生成密钥 */
#define CKF_GENERATE_KEY_PAIR  0x00010000  /* 可生成密钥对 */
#define CKF_DERIVE             0x00020000  /* 可派生密钥 */
#define CKF_WRAP               0x00040000  /* 可包装密钥 */
#define CKF_UNWRAP             0x00080000  /* 可解包密钥 */

示例代码

/* 查询Token支持的机制 */

CK_ULONG mechCount;
CK_MECHANISM_TYPE_PTR mechList;
CK_MECHANISM_INFO mechInfo;
CK_RV rv;

// 1. 获取机制数量
rv = C_GetMechanismList(slotID, NULL_PTR, &mechCount);
if (rv != CKR_OK) {
    printf("获取机制数量失败\n");
    return;
}

// 2. 分配内存,获取机制列表
mechList = malloc(mechCount * sizeof(CK_MECHANISM_TYPE));
rv = C_GetMechanismList(slotID, mechList, &mechCount);

// 3. 打印每个机制的详细信息
for (CK_ULONG i = 0; i < mechCount; i++) {
    rv = C_GetMechanismInfo(slotID, mechList[i], &mechInfo);
    
    printf("机制 %08x:\n", mechList[i]);
    printf("  密钥长度: %lu-%lu\n", mechInfo.ulMinKeySize, mechInfo.ulMaxKeySize);
    printf("  硬件实现: %s\n", (mechInfo.flags & CKF_HW) ? "是" : "否");
    printf("  可签名: %s\n", (mechInfo.flags & CKF_SIGN) ? "是" : "否");
    printf("  可加密: %s\n", (mechInfo.flags & CKF_ENCRYPT) ? "是" : "否");
}

free(mechList);

常用机制详解

RSA机制

机制描述用途
CKM_RSA_PKCS_KEY_PAIR_GENRSA密钥对生成生成RSA密钥
CKM_RSA_PKCSPKCS#1 v1.5签名/加密签名、加密
CKM_RSA_PKCS_PSSRSASSA-PSS签名更安全的签名
CKM_RSA_PKCS_OAEPRSAES-OAEP加密更安全的加密
CKM_RSA_X_509X.509原始RSA不推荐

CKM_RSA_PKCS_PSS参数

typedef struct CK_RSA_PKCS_PSS_PARAMS {
    CK_MECHANISM_TYPE   hashAlg;     /* 哈希算法(如CKM_SHA256) */
    CK_RSA_PKCS_MGF_TYPE mgf;        /* MGF掩码生成函数(如CKG_MGF1_SHA256) */
    CK_ULONG             sLen;       /* 盐值长度 */
} CK_RSA_PKCS_PSS_PARAMS;

AES机制

机制描述模式
CKM_AES_KEY_GENAES密钥生成密钥生成
CKM_AES_ECBAES ECB模式无IV
CKM_AES_CBCAES CBC模式需要16字节IV
CKM_AES_CBC_PADAES CBC+PKCS#7填充需要16字节IV
CKM_AES_CTRAES CTR模式需要计数器参数
CKM_AES_GCMAES GCM模式需要IV和AAD

CKM_AES_CBC参数

CK_BYTE iv[16] = {0x00, 0x01, 0x02, ...};  /* 16字节IV */
CK_MECHANISM mechanism = {CKM_AES_CBC, iv, 16};

CKM_AES_GCM参数

typedef struct CK_GCM_PARAMS {
    CK_BYTE_PTR  pIv;         /* IV指针 */
    CK_ULONG     ulIvLen;     /* IV长度 */
    CK_ULONG     ulIvBits;    /* IV位数(通常与ulIvLen*8相同) */
    CK_BYTE_PTR  pAAD;        /* AAD(附加认证数据) */
    CK_ULONG     ulAADLen;    /* AAD长度 */
    CK_ULONG     ulTagBits;   /* 认证标签位数(如128) */
} CK_GCM_PARAMS;

ECDSA机制

机制描述用途
CKM_EC_KEY_PAIR_GENEC密钥对生成生成ECDSA密钥
CKM_ECDSAECDSA签名签名原始数据
CKM_ECDSA_SHA1SHA1后ECDSA签名签名哈希后数据
CKM_ECDSA_SHA256SHA256后ECDSA签名签名哈希后数据

SHA机制

机制描述输出长度
CKM_SHA_1SHA-1哈希20字节
CKM_SHA256SHA-256哈希32字节
CKM_SHA384SHA-384哈希48字节
CKM_SHA512SHA-512哈希64字节

HMAC机制

/* HMAC机制 */

CK_MECHANISM mechanism = {CKM_SHA256_HMAC, NULL_PTR, 0};
rv = C_SignInit(hSession, &mechanism, hHmacKey);
rv = C_Sign(hSession, data, dataLen, hmac, &hmacLen);

密钥生成机制

RSA密钥生成

CK_MECHANISM mechanism = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
CK_ULONG modulusBits = 2048;
CK_BYTE publicExponent[] = {0x01, 0x00, 0x01};  /* 65537 */

CK_ATTRIBUTE publicKeyTemplate[] = {
    {CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
    {CKA_PUBLIC_EXPONENT, publicExponent, sizeof(publicExponent)},
    // 其他属性...
};

CK_ATTRIBUTE privateKeyTemplate[] = {
    {CKA_SENSITIVE, &bTrue, sizeof(bTrue)},
    {CKA_EXTRACTABLE, &bFalse, sizeof(bFalse)},
    // 其他属性...
};

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

AES密钥生成

CK_MECHANISM mechanism = {CKM_AES_KEY_GEN, NULL_PTR, 0};
CK_ULONG keyLen = 32;  /* 256位 */

CK_ATTRIBUTE keyTemplate[] = {
    {CKA_VALUE_LEN, &keyLen, sizeof(keyLen)},
    {CKA_KEY_TYPE, &aesKeyType, sizeof(aesKeyType)},
    {CKA_CLASS, &secretKeyClass, sizeof(secretKeyClass)},
};

rv = C_GenerateKey(hSession, &mechanism, keyTemplate, 3, &hKey);

密钥派生机制

ECDH密钥派生

CK_ECDH1_DERIVE_PARAMS ecdhParams = {
    CKD_NULL,        /* KDF类型 */
    NULL_PTR,        /* 共享数据 */
    0,               /* 共享数据长度 */
    otherPublicKey,  /* 对方公钥数据 */
    otherPubKeyLen   /* 公钥长度 */
};

CK_MECHANISM mechanism = {CKM_ECDH1_DERIVE, &ecdhParams, sizeof(ecdhParams)};
CK_ATTRIBUTE derivedKeyTemplate[] = {
    {CKA_CLASS, &secretKeyClass, sizeof(secretKeyClass)},
    {CKA_KEY_TYPE, &aesKeyType, sizeof(aesKeyType)},
    {CKA_VALUE_LEN, &keyLen, sizeof(keyLen)},
};

rv = C_DeriveKey(hSession, &mechanism, hPrivateKey, derivedKeyTemplate, 3, &hDerivedKey);

HKDF密钥派生(v3.0新增)

/* CK_HKDF_PARAMS简化展示(完整定义请参考PKCS#11规范) */
typedef struct CK_HKDF_PARAMS {
    CK_BBOOL          bExtract;         /* 是否执行Extract步骤 */
    CK_BBOOL          bExpand;          /* 是否执行Expand步骤 */
    CK_MECHANISM_TYPE prfHashMechanism; /* PRF哈希机制(如CKM_SHA256) */
    CK_ULONG          ulSaltType;       /* 盐值来源类型 */
    CK_BYTE_PTR       pSalt;            /* 盐值数据 */
    CK_ULONG          ulSaltLen;        /* 盐值长度 */
    CK_OBJECT_HANDLE  hSaltKey;         /* 盐值密钥对象(可选) */
    CK_BYTE_PTR       pInfo;            /* Info数据 */
    CK_ULONG          ulInfoLen;        /* Info长度 */
} CK_HKDF_PARAMS;

/* 基础用法示例 */
CK_HKDF_PARAMS hkdfParams = {
    TRUE,           /* 执行Extract */
    TRUE,           /* 执行Expand */
    CKM_SHA256,     /* SHA-256作为PRF */
    CKZ_SALT_SPECIFIED, /* 使用pSalt提供的盐值 */
    salt, saltLen,  /* 盐值 */
    CK_INVALID_HANDLE, /* 不使用hSaltKey */
    info, infoLen   /* Info */
};

CK_MECHANISM mechanism = {CKM_HKDF_DERIVE, &hkdfParams, sizeof(hkdfParams)};
rv = C_DeriveKey(hSession, &mechanism, hBaseKey, template, 3, &hDerivedKey);

本篇小结

Mechanism是PKCS#11的“配方库“,定义了可用的密码算法:

CK_MECHANISM结构

  • type:机制类型(CKM_xxx)
  • pParameter:机制参数(IV、Salt等)
  • ulParameterLen:参数长度

机制查询

  • C_GetMechanismList:获取支持的机制列表
  • C_GetMechanismInfo:获取机制详细信息

常用机制

  • RSA:CKM_RSA_PKCS、CKM_RSA_PKCS_PSS、CKM_RSA_PKCS_OAEP
  • AES:CKM_AES_ECB、CKM_AES_CBC、CKM_AES_GCM
  • ECDSA:CKM_ECDSA、CKM_ECDSA_SHA256
  • SHA:CKM_SHA256、CKM_SHA512
  • HMAC:CKM_SHA256_HMAC
  • 密钥生成:CKM_RSA_PKCS_KEY_PAIR_GEN、CKM_AES_KEY_GEN
  • 密钥派生:CKM_ECDH1_DERIVE、CKM_HKDF_DERIVE

下一节,我们将详细解析AES机制——ECB、CBC、GCM等模式的区别和用法。

【下集预告】

  • ECB是什么?为什么说不安全?

  • CBC是什么?IV如何使用?

  • GCM是什么?AEAD是什么?

下一节,AES机制详解。