在CryptoApi中,如何应用数字签名的技术呢?看了一大通的 MSDN,对里面的概念还是不明白,而且里的头例子程序,如果没有证书的好像不太好用。有哪位仁兄,能不能帮忙解释一下,小生在这里先谢了!

解决方案 »

  1.   

    个人意见:
        如果需要代码签名认证,最好使用工具(如MS的Codesign工具包和IEAK工具包)来完成,调用低层接口太繁琐;
        对CryptoAPI的低层调用可用来进行数据交换的加密和签名。
      

  2.   

    欢迎访问 happysoft.nease.net 
    欢迎各位访问 happysoft.nease.net 谢谢
    ==========================================================
    ZZZZZZZZZZZZzzzzzzz~~~~~~~~~~
      

  3.   

    // 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_)
      

  4.   

    //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_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;
    }