MSDN 上有一篇文章 这里, ,但我还没有走得太远:

p = 139;
g = 5;

CRYPT_DATA_BLOB pblob;
pblob.cbData = sizeof( ULONG );
pblob.pbData = ( LPBYTE ) &p;

CRYPT_DATA_BLOB gblob;
gblob.cbData = sizeof( ULONG );
gblob.pbData = ( LPBYTE ) &g;

HCRYPTKEY hKey;
if ( ::CryptGenKey( m_hCryptoProvider, CALG_DH_SF,
                    CRYPT_PREGEN, &hKey ) )
{
    ::CryptSetKeyParam( hKey, KP_P, ( LPBYTE ) &pblob, 0 );

此处失败 NTE_BAD_DATA. 。我在用着 MS_DEF_DSS_DH_PROV. 。是什么赋予了?

有帮助吗?

解决方案

可能它只是不喜欢您使用的非常短的键。

我发现 该文章的桌面版本 这可能会有所帮助,因为它有一个完整的示例。

编辑:

OP 从示例中意识到,您必须告诉 CryptGenKey 密钥有多长,您可以通过将标志的前 16 位设置为您想要使用的位数来完成此操作。如果将此值保留为 0,您将获得默认密钥长度。这 记录在 评论 设备文档的部分,以及 dw标志 中的参数 桌面文档.

对于 Diffie-Hellman 密钥交换算法,在 Windows XP 及更高版本上,基本提供程序默认为 512 位密钥,增强提供程序(默认)默认为 1024 位密钥。CE 上似乎没有任何关于默认长度的文档。

因此,代码应该是:

BYTE p[64] = { 139 }; // little-endian, all other bytes set to 0
BYTE g[64] = { 5 };

CRYPT_DATA_BLOB pblob;
pblob.cbData = sizeof( p);
pblob.pbData = p;

CRYPT_DATA_BLOB gblob;
gblob.cbData = sizeof( g );
gblob.pbData = g;

HCRYPTKEY hKey;
if ( ::CryptGenKey( m_hCryptoProvider, CALG_DH_SF,
                    ( 512 << 16 ) | CRYPT_PREGEN, &hKey ) )
{
    ::CryptSetKeyParam( hKey, KP_P, ( LPBYTE ) &pblob, 0 );

其他提示

在我看来 KP_P, KP_G, KP_Q 用于 DSS 密钥(数字签名标准?)。对于 Diffie-Hellman 来说,你应该使用 KP_PUB_PARAMS 并通过一个 DATA_BLOB 指向一个 DHPUBKEY_VER3 结构。

请注意,您指向的文章来自 Windows Mobile/Windows CE SDK。CE 的工作方式与桌面/服务器不同,这并不是第一次。

编辑:CE未实施 KP_PUB_PARAMS. 。要在桌面上使用此结构,请参阅 Diffie-Hellman 版本 3 公钥 BLOB.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top