如何在c#中使用Crypt32解密时找到正确的证书

本文关键字:证书 解密 Crypt32 | 更新日期: 2023-09-27 18:15:35

我尝试解密一个加密的文件。发送者发送了2个文件,一个来自端口,一个来自测试环境。我可以解密prod版本,但无法解密测试版本。

当尝试解密好的版本时,我的工具使用我的证书来解密,但是当我尝试解密错误的版本时,它尝试使用发送者的证书来解密。(但我没有发送方的私钥,当然:))

我对发件人说,你做错了什么,但他说,prod和test是一样的,他看到文件上的两个签名,我试图使用错误的证书。

但是我不知道如何使用好的证书?

我使用Crypt32.dll从c#,这里是简化的代码:

// Prepare stream for encoded info
m_callbackFile = decodedFile;
// Set callback for streaming
StreamInfo = Win32.CreateStreamInfo( (int) encodedFile.Length, new Win32.StreamOutputCallbackDelegate( StreamOutputCallback ) );
// Open message to encode
m_hMsg = Win32.OpenMessageToDecode( StreamInfo );
     // Open message to decode: call API:
    hMsg = CryptMsgOpenToDecode(
        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
        bDetached ? CMSG_DETACHED_FLAG : 0,
        0,
        IntPtr.Zero,
        IntPtr.Zero,
        ref StreamInfo
    );
// Process the whole message
Win32.ProcessMessage( m_hMsg, encodedFile );
    // ProcessMessage: read file from piece to piece, and call API:
    bResult = CryptMsgUpdate(
        hMsg.DangerousGetHandle(),
        new IntPtr( pAux ),
        pbData.Length,
        bFinal
    );

// With enveloped messages we have to verify that we got a valid encryption algorithm
Win32.CheckEnvelopeAlg( m_hMsg );
    // CheckEnvelopeAlg: read the crypth algorithm id from message
    bResult = CryptMsgGetParam(
        hMsg,
        dwParamType, // 15 - CMSG_ENVELOPE_ALGORITHM_PARAM
        dwIndex,
        pParam,
        ref cbParam
    );
    // result is:
    AlgId = (CRYPT_ALGORITHM_IDENTIFIER) Marshal.PtrToStructure( pEnvelopeAlg.DangerousGetHandle(), typeof( CRYPT_ALGORITHM_IDENTIFIER ) );
    // "2.16.840.1.101.3.4.1.2"

// Decrypt the message
Win32.Decrypt( m_hMsg );
    // Get recipient cert
    bResult = CryptMsgGetParam(
        hMsg,
        dwParamType, // 19 - CMSG_RECIPIENT_INFO_PARAM
        dwIndex,
        pParam,
        ref cbParam
    );
    // return with SafeNTHeapHandle pCertInfo
    // Open personal cert store
  hStore = CertOpenSystemStore(
      IntPtr.Zero,
      "MY"
    );
  CERT_INFO certInfo = (CERT_INFO) Marshal.PtrToStructure( pCertInfo.DangerousGetHandle(), typeof( CERT_INFO ) );
    // we can read the serial of the cert from this certInfo
    // this serial is our certificate in the prod case, but this serial is the sender's certificate in the uatcase!

我做错了什么?我如何解密这两个文件?我试着找一个工具来观察/分析在windows下加密的文件,但没有找到任何有用的工具:(你能建议一个吗?:))

如何在c#中使用Crypt32解密时找到正确的证书

问题是:文件上有超过1个"收件人"。我做了一个循环,我尝试读取当前"收件人"的证书(及其私钥),但在失败时取下一个"收件人"。

// GetCountOfKeyTransferRecipients
            GetMessageParam( hMsg, Win32.CMSG_RECIPIENT_COUNT_PARAM, out pRecipientsCount );
            Int32 recipientsCount = (Int32) Marshal.ReadInt32( pRecipientsCount.DangerousGetHandle() );
            Logger.Log( "Recipientek száma:" + recipientsCount.ToString(), Logger.Level.ERROR );
            Boolean succes = false;
            Int32 recipientIndex = 0;
            for (recipientIndex = 0; recipientIndex < recipientsCount; recipientIndex++)
            {
                succes = GetCertificateFromStore( hMsg, recipientIndex, out KeyProvInfo ); // try-catch is inside...
                if (succes)
                {
                    break;
                }
            }
            if (!succes)
            {
                throw new Exception( "Get message certificate failed! See previous errors in the log file." );
            }