一、不是一個有效函數
BOOL WINAPI CryptSignMessage( _In_ PCRYPT_SIGN_MESSAGE_PARA pSignPara, _In_ BOOL fDetachedSignature, _In_ DWORD cToBeSigned, _In_ const BYTE *rgpbToBeSigned[], _In_ DWORD rgcbToBeSigned[], _Out_ BYTE *pbSignedBlob, _Inout_ DWORD *pcbSignedBlob );
在Windows的CryptoAPI中,CryptSignMessage是一個用來產生數字簽名的函數,返回值類型是BOOL。此函數需要傳入一個PCRYPT_SIGN_MESSAGE_PARA結構體,包含數字證書、簽名算法等簽名相關的信息。
然而,在myatl.cryptsignisnotafunct中,CryptSignMessage的調用顯然只傳入了前兩個參數,沒有傳入後續的to-be-signed數據等必備參數,因此無法返回有效的數字簽名結果,因此可以得出結論,myatl.cryptsignisnotafunct本質上是無效的函數,其存在的本意應該是作為調試過程中的一個中間函數。
二、關於myatl的來歷
#include "stdafx.h"
#include
extern CComModule _Module;
#include
#include "Example1.h"
HRESULT __stdcall myatl_cryptsignisnotafunct(BSTR bstrSubjectName) //bstrSubjectName是數字證書的主題名
{
CComBSTR bstrCertStoreName(L"MY");
HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, bstrCertStoreName); //打開MY個人證書存儲區
if (!hCertStore)
{
return S_FALSE;
}
PCCERT_CONTEXT pCertContext = NULL;
while (pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext)) //枚舉證書存儲區中的個人證書列表
{
if (lstrcmp(bstrSubjectName, pCertContext->pCertInfo->Subject.pbData) == 0) //pbData是CERT_NAME_INFO結構體,表示Subject的二進制編碼
{
CERT_SIGNED_CONTENT_INFO CertSignedContentInfo;
memset(&CertSignedContentInfo, 0, sizeof(CertSignedContentInfo));
DWORD dwMsgEncodingType = 0;
DWORD dwSignedMessageBlobSize = 0;
BYTE* pbSignedMessageBlob = NULL;
if (CryptSignMessage(&pSignPara, FALSE, 0, NULL, rgcbToBeSigned, NULL, &dwSignedMessageBlobSize))
{
pbSignedMessageBlob = new BYTE[dwSignedMessageBlobSize];
if (CryptSignMessage(&pSignPara, FALSE, 0, NULL, rgcbToBeSigned, pbSignedMessageBlob, &dwSignedMessageBlobSize))
{
CertSignedContentInfo.ToBeSigned.pbData = (BYTE*)rgpbToBeSigned[0];
CertSignedContentInfo.ToBeSigned.cbData = rgcbToBeSigned[0];
CertSignedContentInfo.SignatureAlgorithm.pszObjId = szOID_RSA_SHA1RSA;
CertSignedContentInfo.SignatureAlgorithm.Parameters.cbData = 0;
CertSignedContentInfo.SignatureAlgorithm.Parameters.pbData = NULL;
CertSignedContentInfo.Signature.pbData = pbSignedMessageBlob;
CertSignedContentInfo.Signature.cbData = dwSignedMessageBlobSize;
CERT_BLOB certBlob;
certBlob.cbData = pCertContext->cbCertEncoded;
certBlob.pbData = pCertContext->pbCertEncoded;
CERT_SIGNED_INFO CertSignedInfo;
CertSignedInfo.Issuer = pCertContext->pCertInfo->Issuer;
CertSignedInfo.SerialNumber = pCertContext->pCertInfo->SerialNumber;
CertSignedInfo.Algorithm.pszObjId = szOID_RSA_SHA1RSA;
CertSignedInfo.Algorithm.Parameters.cbData = 0;
CertSignedInfo.Algorithm.Parameters.pbData = NULL;
CertSignedInfo.AuthenticatedAttributes.cAttr = NULL;
CertSignedInfo.AuthenticatedAttributes.rgAttr = NULL;
CertSignedInfo.UnauthenticatedAttributes.cAttr = NULL;
CertSignedInfo.UnauthenticatedAttributes.rgAttr = NULL;
CertSignedInfo.EncryptedHash.cbData = 0;
CertSignedInfo.EncryptedHash.pbData = NULL;
BOOL bResult = ::CryptVerifyCertificateSignatureEx(
NULL,
X509_ASN_ENCODING,
0,
(void*)X509_CERTIFICATE_SIGNATURE,
&certBlob,
0,
&CertSignedContentInfo,
&CertSignedInfo);
if (bResult)
{
delete[] pbSignedMessageBlob;
CertFreeCertificateContext(pCertContext);
CertCloseStore(hCertStore, 0);
return S_OK;
}
}
delete[] pbSignedMessageBlob;
}
}
}
CertCloseStore(hCertStore, 0);
return S_FALSE;
}
myatl.cryptsignisnotafunct是一個Windows的COM組件,包含在頭文件”Example1.h”中,由Visual Studio中的ATL工程使用。該組件的功能是對數字證書進行數字簽名。同時,在頭文件中可以看到這些頭文件都被包含進來:stdafx.h,atlbase.h,atlcom.h。
COM的全稱是Component Object Model,在Windows操作系統中起着重要作用,它是一種跨進程的通信機制,能夠使用不同的語言編寫的組件相互通信。Visual Studio的ATL是微軟提供的一組庫,它封裝了COM API,可以方便地創建和使用COM組件。
三、數字簽名的原理和實現
數字簽名是一種確定數據的發送者是否可信的機制。在數字簽名中,發送者使用自己的私鑰對數據進行簽名,接收者使用發送者的公鑰對數據進行驗證,如果驗證通過,那麼可信度就比較高。
為了保證數字簽名的安全性,必須使用一種安全的加密算法。在myatl.cryptsignisnotafunct中,主要使用了SHA-1(安全散列算法)和RSA(公鑰密碼算法)來實現數字簽名。
數字簽名的核心代碼部分如下所示:
if (CryptSignMessage(&pSignPara, FALSE, 0, NULL, rgcbToBeSigned, NULL, &dwSignedMessageBlobSize))
{
pbSignedMessageBlob = new BYTE[dwSignedMessageBlobSize];
if (CryptSignMessage(&pSignPara, FALSE, 0, NULL, rgcbToBeSigned, pbSignedMessageBlob, &dwSignedMessageBlobSize))
{
CertSignedContentInfo.ToBeSigned.pbData = (BYTE*)rgpbToBeSigned[0];
CertSignedContentInfo.ToBeSigned.cbData = rgcbToBeSigned[0];
CertSignedContentInfo.SignatureAlgorithm.pszObjId = szOID_RSA_SHA1RSA;
CertSignedContentInfo.SignatureAlgorithm.Parameters.cbData = 0;
CertSignedContentInfo.SignatureAlgorithm.Parameters.pbData = NULL;
CertSignedContentInfo.Signature.pbData = pbSignedMessageBlob;
CertSignedContentInfo.Signature.cbData = dwSignedMessageBlobSize;
}
delete[] pbSignedMessageBlob;
}
CryptSignMessage函數用來對一段待簽名數據進行數字簽名,其中,pSignPara是一個PCRYPT_SIGN_MESSAGE_PARA結構體,包含數字證書、簽名算法等簽名相關的信息。rgcbToBeSigned參數是一個DWORD數組,表示各待簽名數據塊的字節數,rgpbToBeSigned則是包含所有待簽名數據塊的指針數組。在上述代碼中,由於myatl.cryptsignisnotafunct僅僅是一段中間代碼,沒有提供實際數據供簽名,因此CryptSignMessage的後續參數不需要給出。
完成數字簽名後,myatl.cryptsignisnotafunct使用依次將待簽名數據和簽名算法等信息填入CERT_SIGNED_CONTENT_INFO結構體中並進行進一步處理。在這個結構體中,ToBeSigned成員是待簽名數據,SignatureAlgorithm成員表示簽名算法,Signature成員則保存了數字簽名數據。
四、總結
myatl.cryptsignisnotafunct是一個不完整的Windows COM組件,其用途是為數字證書提供數字簽名功能,同時也涉及了數字簽名的實現原理。雖然這個組件存在一些問題,但是對學習COM編程和數字簽名技術都有一定的參考意義。
原創文章,作者:SPSPA,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/317272.html
微信掃一掃
支付寶掃一掃