Crypto库实现PKCS7签名与签名验证

时间:2021-04-21 14:45:12

在windows中,可以直接使用微软提供的crypto库实现PKCS7签名与签名验证。签名接口函数为CryptSignMessage,其接口定义为:

  1. BOOL WINAPI CryptSignMessage(
  2. __in          PCRYPT_SIGN_MESSAGE_PARA pSignPara,
  3. __in          BOOL fDetachedSignature,
  4. __in          DWORD cToBeSigned,
  5. __in          const BYTE* rgpbToBeSigned[],
  6. __in          DWORD rgcbToBeSigned[],
  7. __out         BYTE* pbSignedBlob,
  8. __in_out      DWORD* pcbSignedBlob
  9. );

其中,第一个参数为CRYPT_SIGN_MESSAGE_PARA类型,它包含签名过程中一些参数的配置,如签名者证书,证书撤销列表,以及一些授权属性与非授权属性。第二个参数fDetachedSignature用来标识是否发送明文,如果为真,则不发送明文,需在接收方配置明文信息;反之,则发送签名消息的同时发送明文,接收方可从中取出明文。第三、四、五个参数与待签名的明文相关,如果fDetachedSignature为真,则它们都为空;否则,不能为空,第三个参数标识待签名明文的个数,可以有多组明文,第四个参数标识明文串,它是一个指针数组,其中包含每组明文的地址,第五个参数标识每组明文的长度。第六和第七个参数为生成的编码签名串,它是由PKCS7格式转化得到。

验证签名的接口函数有两种,分别为CryptVerifyMessageSignature和CryptVerifyDetachedMessageSignature,前者用来验证包含明文的签名,后者用来验证不包含明文的签名。它们的接口定义分别为:

  1. BOOL WINAPI CryptVerifyMessageSignature(
  2. __in          PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
  3. __in          DWORD dwSignerIndex,
  4. __in          const BYTE* pbSignedBlob,
  5. __in          DWORD cbSignedBlob,
  6. __out         BYTE* pbDecoded,
  7. __in_out      DWORD* pcbDecoded,
  8. __out_opt     PCCERT_CONTEXT* ppSignerCert
  9. );

其中,第一个参数为CRYPT_VERIFY_MESSAGE_PARA类型,它定义了一个获取签名者证书的回调函数,可以设置回调函数为空,默认从签名消息证书库中获取签名者证书。第二个参数dwSignerIndex用来标识签名者索引,因为签名消息可以由多个签名者签名构成,第三和第四个参数为接收到的签名串,第五和第六个参数为解码后得到的明文,第七个参数可以获取签名者证书上下文。

  1. BOOL WINAPI CryptVerifyDetachedMessageSignature(
  2. __in          PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
  3. __in          DWORD dwSignerIndex,
  4. __in          const BYTE* pbDetachedSignBlob,
  5. __in          DWORD cbDetachedSignBlob,
  6. __in          DWORD cToBeSigned,
  7. __in          const BYTE* rgpbToBeSigned[],
  8. __in          DWORD rgcbToBeSigned[],
  9. __out_opt     PCCERT_CONTEXT* ppSignerCert
  10. );

其中,第一和第二个参数与上面一致,第三和第四个参数为接收到的签名串,第五、六、七个参数用来标识明文信息,因为在签名串中不包含明文,第八个参数可以获取签名者证书上下文。