SignedData型と検証SignedData型の署名データを検証するには、CryptVerifyMessageSignatureを呼び出します。*ppSignerCert);pVerifyParaは、検証情報を含んでいるCRYPT_VERIFY_MESSAGE_PARA構造体のアドレスを指定します。dwSignerIndexは、どの署名者の証明書で検証を行うかのインデックスを指定します。pbSignedBlobは、署名されたデータを指定します。cbSignedBlobは、署名されたデータのサイズを指定します。pbDecodedは、デコードされたデータを受け取るバッファを指定します。pcbDecodedは、バッファのサイズを指定します。pbDecodedにNULLを指定した場合、バッファのサイズを受け取ることができます。ppSignerCertは、署名されたデータに含まれる署名者の証明書が返ります。不要な場合は、NULLを指定することができます。CRYPT_VERIFY_MESSAGE_PARA構造体の定義を次に示します。*PCRYPT_VERIFY_MESSAGE_PARA;cbSizeは、構造体のサイズをバイト単位で指定します。dwMsgAndCertEncodingTypeは、エンコーディングタイプを指定します。hCryptProvは、署名を検証するためのCSPのハンドルを指定します。Vista以降では、0を指定します。pfnGetSignerCertificateは、署名者の証明書を検索するコールバック関数のアドレスを指定します。NULLを指定した場合、既定の方法で署名者の証明書が取得されます。pvGetArgは、コールバック関数に渡したい引数を指定します。コールバック関数の定義は、次のようになります。hMsgCertStore);pvGetArgは、CRYPT_VERIFY_MESSAGE_PARA構造体のpvGetArgメンバの値が格納されます。dwCertEncodingTypeは、エンコーディングタイプが格納されます。pSignerIdは、IssuerメンバとSerialNumberメンバを初期化したCERT_INFO構造体のアドレスが格納されます。このような引数を受け取ることができます。hMsgCertStoreは、CryptGetMessageCertificatesの戻り値が格納されます。#7形式のデータを証明書ストアと見立てます。次にコールバック関数の実装例を示します。pSignerContext;}前節で述べたように、署名に使った証明書というのはデフォルトでは署名データに含まれません。含まれていない場合でも対策はあります。それは、IDを基にシステムストアから証明書を検索するという方法です。署名データに証明書が含まれているかのように振舞うことができるのです。今回のプログラムは、前節で作成したsign.datをCryptVerifyMessageSignatureを用いて検証します。TEXT("検証に失敗しました。TEXT("検証に失敗しました。ファイルのサイズの値が署名データのサイズとなります。これを基にメモリを確保し、ファイルを読み取れば署名データを取得することができます。PKCS_7_ASN_ENCODINGを指定するのは当然ですが、X509_ASN_ENCODINGも指定しています。その証明書に含まれる公開鍵を使って秘密鍵で暗号化されたハッシュ値を複合化する必要があるからです。X509_ASN_ENCODINGを指定することになります。CryptVerifyMessageSignatureの呼び出しは、次のようになっています。NULL);第2引数は署名者のインデックスですが、前節では署名者を1人しか設定していないので0を指定します。後はその分のメモリを確保し、2回目のCryptVerifyMessageSignatureで実際に検証を行えることになります。関数が成功するので注意してください。