|
先来创建数字签名,假定其数据来自于一个文件。
//变量声明:
HCRYPTPROV hProv;
// CSP的句柄
HCRYPTHASH hHash;
// 散列的句柄
const int BUFFER = 4096;
// 缓冲区大小常数
BYTE pBuffer[BUFFER];
// 存放读文件内容的缓冲区
BYTE pSignature[256];
// 存放签名的缓冲区
DWORD dSignatureLen = 256;
// 签名的长度
TFileStream *sourceFile;
// 一个文件流
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV—RSA—FULL, 0))
// 连接默认的CSP,接受它的句柄放入hProv
{
// 错误处理
}
if(!CryptCreateHash(hProv, CALG—MD5, 0, 0, &hHash))
// 创建一个散列对象,得到它的句柄放入hHash
{
// 错误处理
}
do
{
dReadLen = sourceFile->Read(pBuffer, BUFFER);
if(!CryptHashData(hHash, pBuffer, dReadLen, 0))
// 根据文件的内容计算散列值
{
// 错误处理
}
}while(!(dReadLen<BUFFER));
if(!CryptSignHash(hHash, AT—SIGNATURE, NULL, 0, pSignature, &dSignatureLen))
//使用私人密钥对散列值进行数字签名
//签名数据放入pSignature,长度放入dSignatureLen
// 错误处理
}
对基于文件的数据签名进行检验。
//变量声明:
HCRYPTPROV hProv;
// CSP的句柄
HCRYPTHASH hHash;
// 散列的句柄
HCRYPTKEY hPublicKey;
// 公共密钥的句柄
const int BUFFER=4096;
// 缓冲区大小常数
BYTE pBuffer[BUFFER];
// 存放读文件内容的缓冲区
TFileStream *sourceFile;// 一个文件流
BYTE pSignature[256];
// 上一段得到的签名的缓冲区
DWORD dSignatureLen;
// 上一段得到的签名的长度
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV—RSA—FULL, 0))
// 连接默认的CSP,接受它的句柄放入hProv
{
// 错误处理
}
if(!CryptGetUserKey(hProv, AT_SIGNATURE, &hPublicKey); // 得到公共密钥的句柄
{
// 错误处理
}
if(!CryptCreateHash(hProv, CALG—MD5, 0, 0, &hHash)) // 创建一个散列对象,得到它的句柄放入hHash
{
// 错误处理
}
do
{
dReadLen = sourceFile->Read(pBuffer, BUFFER);
if(!CryptHashData(hHash, pBuffer, dReadLen, 0))
// 根据文件的内容计算散列值
{
// 错误处理
}
}while(!(dReadLen<BUFFER));
if(!CryptVerifySignature(hHash, pSignature, dSignatureLen, hPublicKey, NULL, 0))
{
if(GetLastError()==NTE—BAD—SIGNATURE) ShowMessage(″文件已被修改″);
}
else
{
ShowMessage(″文件没被修改″);
}
以上是一个数字签名的简单实现,得到的签名数据可以单独保存,也可以分开保存。
引用结束
请大家相信我是按照上述代码及MSDN有关Crypt函数帮助做过的,前面创建CSP句柄、hash句柄及hash运算都实现了,可以用CryptGetParam()函数获得hash的值(当然是乱码)。问题就在进行数字签名时:
if(!CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, pSignature, &dSignatureLen))
//使用私人密钥对散列值进行数字签名
//签名数据放入pSignature,长度放入dSignatureLen
// 错误处理
}
|