CryptSignHashA 函数 (wincrypt.h)
语法
BOOL CryptSignHashA(
[in] HCRYPTHASH hHash,
[in] DWORD dwKeySpec,
[in] LPCSTR szDescription,
[in] DWORD dwFlags,
[out] BYTE *pbSignature,
[in, out] DWORD *pdwSigLen
);
参数
[in] hHash
要签名的 哈希对象的句柄。
[in] dwKeySpec
标识要从提供程序容器使用的私钥。 它可以AT_KEYEXCHANGE或AT_SIGNATURE。
最初创建密钥对时指定的签名算法。
Microsoft基本加密提供程序支持的唯一签名算法是 RSA 公钥算法。
[in] szDescription
此参数不再使用,必须设置为 NULL 以防止安全漏洞。 但是,仍支持在 Microsoft 基本加密提供程序中实现向后兼容性。
[in] dwFlags
定义了以下标志值。
价值 | 意义 |
---|---|
|
与 RSA 提供程序一起使用。 哈希 对象标识符(OID)未放置在 RSA 公钥加密中。 如果未设置此标志,则默认签名中的哈希 OID 在 PKCS #1 的 DigestInfo 定义中指定。 |
|
不使用此标志。 |
|
使用 ANSI X9.31 标准中指定的 RSA 签名填充方法。 |
[out] pbSignature
指向接收签名数据的缓冲区的指针。
此参数可以 NULL 来设置用于内存分配的缓冲区大小。 有关详细信息,请参阅 检索未知长度的数据。
[in, out] pdwSigLen
指向 DWORD 值的指针,该值指定 pbSignature 缓冲区的大小(以字节为单位)。 函数返回时,DWORD 值包含缓冲区中存储的字节数。
返回值
如果函数成功,该函数将返回 true
如果该函数失败,则返回 FALSE。 有关扩展错误信息,请调用 GetLastError。
前面为“NTE”的错误代码由所使用的特定 CSP 生成。 下面是一些可能的错误代码。
返回代码 | 描述 |
---|---|
|
其中一个参数指定无效的句柄。 |
|
其中一个参数包含无效的值。 这通常是无效的指针。 |
|
pbSignature 参数指定的缓冲区不够大,无法容纳返回的数据。 所需的缓冲区大小(以字节为单位)位于 pdwSigLenDWORD 值中。 |
|
hHash 句柄指定此 CSP 不支持的算法,或者 dwKeySpec 参数的值不正确。 |
|
dwFlags 参数为非零。 |
|
hHash 参数指定的哈希对象无效。 |
|
找不到创建哈希对象时指定的 CSP 上下文。 |
|
dwKeySpec 指定的私钥不存在。 |
|
在操作期间,CSP 内存不足。 |
言论
在调用此函数之前,必须调用 CryptCreateHash 函数才能获取哈希对象的句柄。 然后,使用 CryptHashData 或 CryptHashSessionKey 函数向哈希对象添加数据或会话键。 CryptSignHash 函数完成哈希。
虽然 DSS CSP 支持使用 MD5 和 SHA 哈希算法进行哈希处理,但 DSS CSP 仅支持对 SHA 哈希进行签名。
调用此函数后,无法向哈希添加更多数据。 对 CryptHashData 或 CryptHashSessionKey 的其他调用失败。
应用程序使用哈希完成后,通过调用 CryptDestroyHash 函数来销毁哈希对象。
默认情况下,Microsoft RSA 提供程序使用 PKCS #1 填充方法进行签名。 签名的 DigestInfo 元素中的哈希 OID 会自动设置为与哈希对象关联的算法 OID。 使用 CRYPT_NOHASHOID 标志将导致从签名中省略此 OID。
有时,必须对其他位置生成的哈希值进行签名。 这可以通过使用以下操作序列来完成:
- 使用 CryptCreateHash创建哈希对象。
- 通过使用 CryptSetHashParam中的 dwParam 参数 HP_HASHVAL 值设置哈希对象中的哈希值。
- 使用 CryptSignHash 并获取数字签名块对哈希值进行签名。
- 使用 CryptDestroyHash销毁哈希对象。
例子
以下示例演示如何先对要签名的数据进行哈希处理,然后使用 CryptSignHash 函数对哈希进行签名。
//-------------------------------------------------------------
// Declare and initialize variables.
HCRYPTPROV hProv;
BYTE *pbBuffer= (BYTE *)"Sample data that is to be signed.";
DWORD dwBufferLen = strlen((char *)pbBuffer)+1;
HCRYPTHASH hHash;
//--------------------------------------------------------------------
// This code assumes that a cryptographic context handle, hProv,
// and a hash handle, hHash, are available.
// For code needed to acquire the context, see "Example C Program:
// Signing a Hash and Verifying the Hash Signature."
//--------------------------------------------------------------------
// Compute the cryptographic hash of the buffer.
if(CryptHashData(
hHash,
pbBuffer,
dwBufferLen,
0))
{
printf("The data buffer has been hashed.\n");
}
else
{
printf("Error during CryptHashData.\n");
exit(1);
}
//--------------------------------------------------------------------
// Determine the size of the signature and allocate memory.
dwSigLen= 0;
if(CryptSignHash(
hHash,
AT_SIGNATURE,
szDescription,
0,
NULL,
&dwSigLen))
{
printf("Signature length %d found.\n",dwSigLen);
}
else
{
printf("Error during CryptSignHash\n");
exit(1);
}
//--------------------------------------------------------------------
// Allocate memory for the signature buffer.
if(pbSignature = (BYTE *)malloc(dwSigLen))
{
printf("Memory allocated for the signature.\n");
}
else
{
printf("Out of memory\n");
exit(1);
}
//--------------------------------------------------------------------
// Sign the hash object.
if(CryptSignHash(
hHash,
AT_SIGNATURE,
szDescription,
0,
pbSignature,
&dwSigLen))
{
printf("pbSignature is the hash signature.\n");
}
else
{
printf("Error during CryptSignHash.\n");
exit(1);
}
//--------------------------------------------------------------------
// Destroy the hash object.
if(hHash)
CryptDestroyHash(hHash);
有关包含此代码上下文的完整示例,请参阅 示例 C 程序:对哈希进行签名并验证哈希签名。
注意
wincrypt.h 标头将 CryptSignHash 定义为一个别名,该别名根据 UNICODE 预处理器常量的定义自动选择此函数的 ANSI 或 Unicode 版本。 将中性编码别名与不中性编码的代码混合使用可能会导致编译或运行时错误不匹配。 有关详细信息,请参阅函数原型的
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows XP [仅限桌面应用] |
支持的最低服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | 窗户 |
标头 | wincrypt.h |
库 | Advapi32.lib |
DLL | Advapi32.dll |