You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Microsoft CNG生成DSA密钥时BCryptSetProperty调用失败求助

解决BCryptSetProperty设置DSA参数返回STATUS_NOT_SUPPORTED的问题

核心问题分析

你的代码存在两个致命错误:

  • 错误地将BCRYPT_DSA_PARAMETERS属性绑定到算法句柄hAlg,实际上该属性属于密钥级,必须设置在**密钥句柄hKey**上
  • DSA参数Blob中的Seed、q、Modulus、Generator字段未初始化,属于无效数据,不符合FIPS标准要求

修正后的完整代码示例

以下是可正确生成DSA密钥对的C语言实现:

#include <windows.h>
#include <bcrypt.h>
#include <iostream>
#include <cstring>

#pragma comment(lib, "bcrypt.lib")

#define KEYSIZE 3072
#define CBSEEDLENGTH 43
#define CBGROUPSIZE 32
#define CBKEYLENGTH 384  // 3072位密钥对应字节数

struct _DSA_PARAMETER_BLOB
{
    BCRYPT_DSA_PARAMETER_HEADER_V2 H;
    UCHAR Seed[CBSEEDLENGTH];      // 大端格式
    UCHAR q[CBGROUPSIZE];          // 大端格式,256位素数
    UCHAR Modulus[CBKEYLENGTH];    // 大端格式,3072位素数
    UCHAR Generator[CBKEYLENGTH];  // 大端格式,生成元
};

int main()
{
    NTSTATUS nts;
    BCRYPT_ALG_HANDLE hAlg = NULL;
    BCRYPT_KEY_HANDLE hKey = NULL;

    // 打开DSA算法提供者
    nts = BCryptOpenAlgorithmProvider(&hAlg,
        BCRYPT_DSA_ALGORITHM,
        MS_PRIMITIVE_PROVIDER,
        0);
    if (STATUS_SUCCESS != nts)
    {
        std::cout << "BCryptOpenAlgorithmProvider失败,状态码0X" << std::hex << nts << std::endl;
        return (int)nts;
    }

    // 创建空密钥对容器
    nts = BCryptGenerateKeyPair(hAlg,
        &hKey,
        KEYSIZE,
        0);
    if (STATUS_SUCCESS != nts)
    {
        std::cout << "BCryptGenerateKeyPair失败,状态码0X" << std::hex << nts << std::endl;
        goto cleanup1;
    }

    // 初始化DSA参数Blob(需替换为合法的FIPS 186-3标准参数)
    _DSA_PARAMETER_BLOB dpb = {0};
    dpb.H.cbLength = sizeof(dpb);
    dpb.H.dwMagic = BCRYPT_DSA_PARAMETERS_MAGIC_V2;
    dpb.H.cbKeyLength = CBKEYLENGTH;
    dpb.H.hashAlgorithm = DSA_HASH_ALGORITHM_SHA512;
    dpb.H.standardVersion = DSA_FIPS186_3;
    dpb.H.cbSeedLength = CBSEEDLENGTH;
    dpb.H.cbGroupSize = CBGROUPSIZE;
    // 迭代次数设为64(大端格式存储)
    dpb.H.Count[3] = 64;

    // 注意:此处需填充合法的DSA参数值(示例仅做格式演示,实际需使用合规素数)
    memset(dpb.q, 0xFF, CBGROUPSIZE);  // 示例256位q值
    // 请将Seed、Modulus、Generator替换为符合标准的大端数值

    // 核心修正:将参数设置到密钥句柄而非算法句柄
    nts = BCryptSetProperty(hKey,
        BCRYPT_DSA_PARAMETERS,
        (PUCHAR)&dpb,
        sizeof(dpb),
        0);
    if (STATUS_SUCCESS != nts)
    {
        std::cout << "BCryptSetProperty失败,状态码0X" << std::hex << nts << std::endl;
        goto cleanup2;
    }

    // 完成密钥对生成
    nts = BCryptFinalizeKeyPair(hKey, 0);
    if (STATUS_SUCCESS != nts)
    {
        std::cout << "BCryptFinalizeKeyPair失败,状态码0X" << std::hex << nts << std::endl;
        goto cleanup2;
    }

    std::cout << "DSA密钥对生成成功" << std::endl;

cleanup2:
    if (hKey)
        BCryptDestroyKey(hKey);
cleanup1:
    if (hAlg)
        BCryptCloseAlgorithmProvider(hAlg, 0);

    return (int)nts;
}

关键注意事项

  • 属性绑定对象:BCRYPT_DSA_PARAMETERS是密钥专属属性,必须在BCryptGenerateKeyPair之后、BCryptFinalizeKeyPair之前,绑定到密钥句柄hKey
  • 参数合规性:Seed、q、Modulus、Generator必须是符合FIPS 186-3标准的大端格式数值,无效值会导致操作失败
  • 哈希匹配:3072位DSA密钥搭配DSA_HASH_ALGORITHM_SHA512是合法组合,需确保q的长度与哈希输出长度匹配

内容的提问来源于stack exchange,提问作者trindflo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:35:04