在CryptoApi中,如何应用数字签名的技术呢? 在CryptoApi中,如何应用数字签名的技术呢?看了一大通的 MSDN,对里面的概念还是不明白,而且里的头例子程序,如果没有证书的好像不太好用。有哪位仁兄,能不能帮忙解释一下,小生在这里先谢了! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 个人意见: 如果需要代码签名认证,最好使用工具(如MS的Codesign工具包和IEAK工具包)来完成,调用低层接口太繁琐; 对CryptoAPI的低层调用可用来进行数据交换的加密和签名。 欢迎访问 happysoft.nease.net 欢迎各位访问 happysoft.nease.net 谢谢==========================================================ZZZZZZZZZZZZzzzzzzz~~~~~~~~~~ // crypto.h: interface for the crypto class.//我的crypto类//////////////////////////////////////////////////////////////////////#include "wincrypt.h"#if !defined(AFX_CRYPTO_H__E361597E_6B23_4BEA_A9BB_0C291CD636BB__INCLUDED_)#define AFX_CRYPTO_H__E361597E_6B23_4BEA_A9BB_0C291CD636BB__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class crypto {public: BOOL Verify(CString strPathName); BOOL Sign(CString strPathName); crypto(); virtual ~crypto();protected: BOOL Load(LPCTSTR lpszFileNameEX,void* pBuf);//读入对摘要的加密数据 BOOL Save(CString strPathNameEX,void* pBuf,UINT nCount);//存入对摘要的加密数据 BOOL Init();// 输出public key 到 PUBLICKEYBOLB void HandleError(char* s);private: //BOOL a; BYTE* pbBuffer;//待签名或认证文件的数据 LPTSTR szDescription; DWORD dwBufferLen; BYTE *pbKeyBlob;//导出的公钥Blob BYTE *pbSignature;//已签名的HASH数据 DWORD dwSignLen;//签名数据长度 DWORD dwBlobLen;//Blob长度 HCRYPTKEY hPubKey;//公钥句柄 HCRYPTPROV hProv;//cryptographic service provider (CSP)句柄. HCRYPTHASH hHash;//HASH句柄 HCRYPTKEY hKey;//公/私钥对句柄 };#endif // !defined(AFX_CRYPTO_H__E361597E_6B23_4BEA_A9BB_0C291CD636BB__INCLUDED_) //cpp文件#include "stdafx.h"#include "sign1.h"#include "crypto.h"#include <stdio.h>#include <windows.h>#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endifcrypto::crypto(){ szDescription = "Test Data Description"; if(CryptAcquireContext( &hProv, NULL, NULL, PROV_RSA_FULL, 0)) { HandleError("CSP context acquired.\n");}else{ HandleError("Error during CryptAcquireContext.");}if(CryptGetUserKey( //生成公/私钥对 hProv, AT_SIGNATURE, &hKey)) { HandleError("The signature key has been acquired. \n");}else{ HandleError("Error during CryptGetUserKey for signkey.");} //Init();}crypto::~crypto(){ if(pbSignature) delete pbSignature; if(hProv) CryptReleaseContext(hProv, 0); if (pbKeyBlob) delete pbKeyBlob;}void crypto::HandleError(char *s){ TRACE(s);}BOOL crypto::Sign(CString strPathName){//创建 hash object.//Init(); CFile file; file.Open(strPathName,CFile::modeRead); dwBufferLen = file.GetLength(); pbBuffer=new BYTE[dwBufferLen];//@@先分配内存 file.Read (pbBuffer,dwBufferLen); //AfxMessageBox((char*)pbBuffer); file.Close();if(CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash)) { //AfxMessageBox((char*)hHash); //CFile file; //file.Open("c:\\h.a",CFile::modeCreate|CFile::modeWrite); //file.Write((void*)hHash,1000); HandleError("Hash object created. \n");}else{ HandleError("Error during CryptCreateHash.");}// 用MD5摘要数据if(CryptHashData( hHash, pbBuffer, dwBufferLen, 0)) { TRACE("The data buffer has been hashed.\n");}else{ TRACE("Error during CryptHashData.");}//--------------------------------------------------------------------// 计算要分配pbSignature的内存大小dwSignLen= 0;if(CryptSignHash( hHash, AT_SIGNATURE, szDescription, 0, NULL, &dwSignLen)) { //TRACE("Signature length %d found.\n",dwSigLen); //HandleError(}else{ HandleError("Error during CryptSignHash.");}//--------------------------------------------------------------------if(pbSignature = new BYTE[dwSignLen])//@@{ //TRACE("%d",dwSignLen); HandleError("Memory allocated for the signature.\n");}else{ HandleError("Out of memory.");}//--------------------------------------------------------------------// 用RSA签名HASH数据if(CryptSignHash( hHash, AT_SIGNATURE, szDescription, 0, pbSignature, &dwSignLen)) { HandleError("pbSignature is the hash signature.\n");}else{ HandleError("Error during CryptSignHash.");}if(hHash) CryptDestroyHash(hHash);//销毁HASH对象 Save(strPathName,pbSignature,dwSignLen); //@@pbSignature=NULL;if(pbSignature) delete pbSignature;if(pbBuffer) delete pbBuffer;HandleError("The hash object has been destroyed.\n");HandleError("The signing phase of this program is completed.\n\n");return TRUE;}BOOL crypto::Verify(CString strPathName){ CFile file; BOOL breturn; file.Open(strPathName,CFile::modeRead); dwBufferLen = file.GetLength(); pbBuffer=new BYTE[dwBufferLen];//@@先分配内存 file.Read (pbBuffer,dwBufferLen); //AfxMessageBox((char*)pbBuffer); file.Close(); Init(); strPathName+=".sgn"; if(!Load(strPathName,pbSignature))return FALSE; //Load("a.pbk",pbKeyBlob,strlen((char*)pbKeyBlob)+1);if(CryptImportKey(//从pbKeyBlob中导入公钥到CSP,并且返回公钥到hPubKey hProv, pbKeyBlob, dwBlobLen, 0, 0, &hPubKey)){ //AfxMessageBox((char*)hPubKey); HandleError("The key has been imported.\n"); //CFile file; //file.Open("c:\\a.a",CFile::modeCreate|CFile::modeWrite); //file.Write((void*)hPubKey,1000);}else{ AfxMessageBox("Public key import failed.");}//--------------------------------------------------------------------// Create a new hash object.if(CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash)) { HandleError("The hash object has been recreated. \n");}else{ HandleError("Error during CryptCreateHash.");}//--------------------------------------------------------------------// Compute the cryptographic hash of the buffer.if(CryptHashData( hHash, pbBuffer, dwBufferLen, 0)) { HandleError("The new has been created.\n");}else{ HandleError("Error during CryptHashData.");}//--------------------------------------------------------------------// Validate the digital signature.dwSignLen= 0;CryptSignHash( hHash, AT_SIGNATURE, szDescription, 0, NULL, &dwSignLen);if(CryptVerifySignature( hHash, pbSignature, dwSignLen, hPubKey, szDescription, 0)) { breturn =TRUE;}else{ breturn =FALSE;}if(hHash) CryptDestroyHash(hHash);if(pbBuffer) delete pbBuffer;if (pbSignature) delete pbSignature;if(pbKeyBlob) delete pbKeyBlob;return breturn;}BOOL crypto::Save(CString strPathName,void* pBuf,UINT nCount){ CFile file; strPathName+=".sgn"; if(file.Open(strPathName,CFile::modeRead)) { CString strTemp; strTemp.Format("该文件已签过名,覆盖%s吗",strPathName); if(AfxMessageBox(strTemp,MB_YESNO)==IDNO)return FALSE; file.Close(); } file.Open(strPathName,CFile::modeCreate|CFile::modeWrite); file.Write(pBuf,nCount); file.Close(); CString strTemp; strTemp.Format("签名完毕!\n文件%s已经存盘",strPathName); AfxMessageBox(strTemp); return TRUE;}BOOL crypto::Load(LPCTSTR lpszFileName, void *pBuf)//@@这样声明,不改变实参?{//@@问题:没有读进pbSignature CFile file; TRACE("%d",dwSignLen); //@@pBuf = new BYTE[nCount]; if(!file.Open(lpszFileName,CFile::modeRead)) { CString strTemp; strTemp.Format("文件%s不存在!",lpszFileName); AfxMessageBox(strTemp); //file.Close(); return FALSE; } //file.Open(lpszFileName,CFile::modeCreate|CFile::modeWrite); DWORD dwFileLen=file.GetLength(); //@@file.Read(pBuf,nCount); pbSignature= new BYTE[dwFileLen]; file.Read(pbSignature,dwFileLen); file.Close(); //CString strTemp; //strTemp.Format("文件%s已经存盘",lpszFileName); //AfxMessageBox(strTemp); return TRUE;}BOOL crypto::Init()// 输出public key 到 PUBLICKEYBOLB {if(CryptExportKey( hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwBlobLen)) { HandleError("Size of the blob for the public key determined. \n");}else{ HandleError("Error computing blob length.");}//--------------------------------------------------------------------// 分配内存 for the pbKeyBlob.if(pbKeyBlob = new BYTE[dwBlobLen]) { TRACE("Memory has been allocated for the blob. \n");}else{ TRACE("Out of memory. \n");}//--------------------------------------------------------------------// Do the actual exporting into the key blob.if(CryptExportKey( hKey, NULL, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen)){ TRACE("Contents have been written to the blob. \n");}else{ TRACE("Error during CryptExportKey.");}return TRUE;} 学MFC有用吗?要多少时间? CImage缩放,图片量可能比较多,应该怎么做 dll一定要结合lib使用吗? VC怎么传递数组的指针? VC驿站-学习VC好地方 怎样单文档转多文档 高分求VC群号:)希望大家把知道的告诉小弟一起学习。为中国的软件努力 一个问题:关于修改基本类 有没有做过海量数据导入导出的(从access&excel&dbf导入到sql),给我点思路好吗? 关于VC编译的怪异问题 如何做一个关机程序 请媒体开发的高手进来了(关于音频的)
如果需要代码签名认证,最好使用工具(如MS的Codesign工具包和IEAK工具包)来完成,调用低层接口太繁琐;
对CryptoAPI的低层调用可用来进行数据交换的加密和签名。
欢迎各位访问 happysoft.nease.net 谢谢
==========================================================
ZZZZZZZZZZZZzzzzzzz~~~~~~~~~~
//我的crypto类
//////////////////////////////////////////////////////////////////////
#include "wincrypt.h"#if !defined(AFX_CRYPTO_H__E361597E_6B23_4BEA_A9BB_0C291CD636BB__INCLUDED_)
#define AFX_CRYPTO_H__E361597E_6B23_4BEA_A9BB_0C291CD636BB__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000class crypto
{
public:
BOOL Verify(CString strPathName); BOOL Sign(CString strPathName);
crypto();
virtual ~crypto();protected:
BOOL Load(LPCTSTR lpszFileNameEX,void* pBuf);//读入对摘要的加密数据
BOOL Save(CString strPathNameEX,void* pBuf,UINT nCount);//存入对摘要的加密数据
BOOL Init();// 输出public key 到 PUBLICKEYBOLB
void HandleError(char* s);
private:
//BOOL a;
BYTE* pbBuffer;//待签名或认证文件的数据
LPTSTR szDescription; DWORD dwBufferLen;
BYTE *pbKeyBlob;//导出的公钥Blob
BYTE *pbSignature;//已签名的HASH数据
DWORD dwSignLen;//签名数据长度
DWORD dwBlobLen;//Blob长度
HCRYPTKEY hPubKey;//公钥句柄
HCRYPTPROV hProv;//cryptographic service provider (CSP)句柄.
HCRYPTHASH hHash;//HASH句柄
HCRYPTKEY hKey;//公/私钥对句柄
};#endif // !defined(AFX_CRYPTO_H__E361597E_6B23_4BEA_A9BB_0C291CD636BB__INCLUDED_)
#include "stdafx.h"
#include "sign1.h"
#include "crypto.h"#include <stdio.h>
#include <windows.h>
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
crypto::crypto()
{
szDescription = "Test Data Description";
if(CryptAcquireContext(
&hProv,
NULL,
NULL,
PROV_RSA_FULL,
0))
{
HandleError("CSP context acquired.\n");
}
else
{
HandleError("Error during CryptAcquireContext.");
}
if(CryptGetUserKey( //生成公/私钥对
hProv,
AT_SIGNATURE,
&hKey))
{
HandleError("The signature key has been acquired. \n");
}
else
{
HandleError("Error during CryptGetUserKey for signkey.");
} //Init();
}crypto::~crypto()
{
if(pbSignature) delete pbSignature;
if(hProv) CryptReleaseContext(hProv, 0);
if (pbKeyBlob) delete pbKeyBlob;}void crypto::HandleError(char *s)
{
TRACE(s);
}BOOL crypto::Sign(CString strPathName)
{//创建 hash object.
//Init();
CFile file;
file.Open(strPathName,CFile::modeRead); dwBufferLen = file.GetLength();
pbBuffer=new BYTE[dwBufferLen];//@@先分配内存
file.Read (pbBuffer,dwBufferLen);
//AfxMessageBox((char*)pbBuffer);
file.Close();if(CryptCreateHash(
hProv,
CALG_MD5,
0,
0,
&hHash))
{
//AfxMessageBox((char*)hHash);
//CFile file;
//file.Open("c:\\h.a",CFile::modeCreate|CFile::modeWrite);
//file.Write((void*)hHash,1000);
HandleError("Hash object created. \n");
}
else
{
HandleError("Error during CryptCreateHash.");
}
// 用MD5摘要数据if(CryptHashData(
hHash,
pbBuffer,
dwBufferLen,
0))
{
TRACE("The data buffer has been hashed.\n");
}
else
{
TRACE("Error during CryptHashData.");
}
//--------------------------------------------------------------------
// 计算要分配pbSignature的内存大小dwSignLen= 0;
if(CryptSignHash(
hHash,
AT_SIGNATURE,
szDescription,
0,
NULL,
&dwSignLen))
{
//TRACE("Signature length %d found.\n",dwSigLen);
//HandleError(
}
else
{
HandleError("Error during CryptSignHash.");
}
//--------------------------------------------------------------------if(pbSignature = new BYTE[dwSignLen])//@@
{
//TRACE("%d",dwSignLen);
HandleError("Memory allocated for the signature.\n");
}
else
{
HandleError("Out of memory.");
}
//--------------------------------------------------------------------
// 用RSA签名HASH数据if(CryptSignHash(
hHash,
AT_SIGNATURE,
szDescription,
0,
pbSignature,
&dwSignLen))
{
HandleError("pbSignature is the hash signature.\n");
}
else
{
HandleError("Error during CryptSignHash.");
}
if(hHash) CryptDestroyHash(hHash);//销毁HASH对象
Save(strPathName,pbSignature,dwSignLen);
//@@pbSignature=NULL;
if(pbSignature) delete pbSignature;
if(pbBuffer) delete pbBuffer;
HandleError("The hash object has been destroyed.\n");
HandleError("The signing phase of this program is completed.\n\n");
return TRUE;
}
BOOL crypto::Verify(CString strPathName)
{
CFile file;
BOOL breturn;
file.Open(strPathName,CFile::modeRead); dwBufferLen = file.GetLength();
pbBuffer=new BYTE[dwBufferLen];//@@先分配内存
file.Read (pbBuffer,dwBufferLen);
//AfxMessageBox((char*)pbBuffer);
file.Close();
Init();
strPathName+=".sgn";
if(!Load(strPathName,pbSignature))return FALSE;
//Load("a.pbk",pbKeyBlob,strlen((char*)pbKeyBlob)+1);if(CryptImportKey(//从pbKeyBlob中导入公钥到CSP,并且返回公钥到hPubKey
hProv,
pbKeyBlob,
dwBlobLen,
0,
0,
&hPubKey))
{
//AfxMessageBox((char*)hPubKey);
HandleError("The key has been imported.\n");
//CFile file;
//file.Open("c:\\a.a",CFile::modeCreate|CFile::modeWrite);
//file.Write((void*)hPubKey,1000);
}
else
{
AfxMessageBox("Public key import failed.");
}
//--------------------------------------------------------------------
// Create a new hash object.if(CryptCreateHash(
hProv,
CALG_MD5,
0,
0,
&hHash))
{
HandleError("The hash object has been recreated. \n");
}
else
{
HandleError("Error during CryptCreateHash.");
}
//--------------------------------------------------------------------
// Compute the cryptographic hash of the buffer.if(CryptHashData(
hHash,
pbBuffer,
dwBufferLen,
0))
{
HandleError("The new has been created.\n");
}
else
{
HandleError("Error during CryptHashData.");
}
//--------------------------------------------------------------------
// Validate the digital signature.
dwSignLen= 0;
CryptSignHash(
hHash,
AT_SIGNATURE,
szDescription,
0,
NULL,
&dwSignLen);
if(CryptVerifySignature(
hHash,
pbSignature,
dwSignLen,
hPubKey,
szDescription,
0))
{
breturn =TRUE;
}
else
{
breturn =FALSE;
}
if(hHash) CryptDestroyHash(hHash);if(pbBuffer) delete pbBuffer;
if (pbSignature) delete pbSignature;
if(pbKeyBlob) delete pbKeyBlob;return breturn;
}BOOL crypto::Save(CString strPathName,void* pBuf,UINT nCount)
{
CFile file;
strPathName+=".sgn";
if(file.Open(strPathName,CFile::modeRead))
{
CString strTemp;
strTemp.Format("该文件已签过名,覆盖%s吗",strPathName);
if(AfxMessageBox(strTemp,MB_YESNO)==IDNO)return FALSE;
file.Close();
}
file.Open(strPathName,CFile::modeCreate|CFile::modeWrite);
file.Write(pBuf,nCount);
file.Close();
CString strTemp;
strTemp.Format("签名完毕!\n文件%s已经存盘",strPathName);
AfxMessageBox(strTemp);
return TRUE;
}BOOL crypto::Load(LPCTSTR lpszFileName, void *pBuf)//@@这样声明,不改变实参?
{//@@问题:没有读进pbSignature
CFile file;
TRACE("%d",dwSignLen); //@@pBuf = new BYTE[nCount];
if(!file.Open(lpszFileName,CFile::modeRead))
{
CString strTemp;
strTemp.Format("文件%s不存在!",lpszFileName);
AfxMessageBox(strTemp);
//file.Close();
return FALSE;
}
//file.Open(lpszFileName,CFile::modeCreate|CFile::modeWrite);
DWORD dwFileLen=file.GetLength();
//@@file.Read(pBuf,nCount);
pbSignature= new BYTE[dwFileLen]; file.Read(pbSignature,dwFileLen);
file.Close();
//CString strTemp;
//strTemp.Format("文件%s已经存盘",lpszFileName);
//AfxMessageBox(strTemp);
return TRUE;
}BOOL crypto::Init()// 输出public key 到 PUBLICKEYBOLB
{
if(CryptExportKey(
hKey,
NULL,
PUBLICKEYBLOB,
0,
NULL,
&dwBlobLen))
{
HandleError("Size of the blob for the public key determined. \n");
}
else
{
HandleError("Error computing blob length.");
}
//--------------------------------------------------------------------
// 分配内存 for the pbKeyBlob.if(pbKeyBlob = new BYTE[dwBlobLen])
{
TRACE("Memory has been allocated for the blob. \n");
}
else
{
TRACE("Out of memory. \n");
}
//--------------------------------------------------------------------
// Do the actual exporting into the key blob.if(CryptExportKey(
hKey,
NULL,
PUBLICKEYBLOB,
0,
pbKeyBlob,
&dwBlobLen))
{
TRACE("Contents have been written to the blob. \n");
}
else
{
TRACE("Error during CryptExportKey.");
}
return TRUE;
}