【问题标题】:Porting c++ Pkcs7 sign to c#将 c++ Pkcs7 符号移植到 c#
【发布时间】:2020-06-11 16:10:07
【问题描述】:

出于维护原因,我正在将一个 c++ 库移植到 c#。我非常接近完成它,但我有这段代码被翻译成 base64,它不返回相同的值。

输入:“probando”

C++

CryptSignMessage(&signParameters,
true,
1,
MessageArray,
MessageSizeArray,
NULL,
&signature.length)

其中使用 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING 作为编码类型

C++ 输出

MIIB8gYJKoZIhvcNAQcCoIIB4zCCAd8CAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGCAb4wggG6AgEBMIGWMH8xEjAQBgoJkiaJk/IsZAEZFgJhcjETMBEGCgmSJomT8ixkARkWA2NvbTEcMBoGCgmSJomT8ixkARkWDGJhbmNvZ2FsaWNpYTEVMBMGCgmSJomT8ixkARkWBWJnY216MR8wHQYDVQQDExZHYWxpY2lhIE9mZmljZSBDQS1TSEEyAhMbAAARQ28x78yrZlirAAEAABFDMAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEggEAA1sSjgNMqSOQaElqHU1Mr0+aOqEwCFdhZAZzacFKs9dPGhUtR9I444YF5+422WJ+A7pd9wAlgejMflhF6lLr8ty/5pyy5BudNq4y1CIx7JSX87+7H1j2QIVIe1mPnKM1/IBD2g5IXDaTqt6S0QFVV9VRKjbe3fVCBo7hfV7gIo19nlBWi2eddEkOwUbqIDcfG/OpSeSkQvqxS/i215Cr3JpXnSSWRrB9ZDg956PI2j0nnAXnOZx/rYARy3btr+CXq1BHsCMclqEyjRZrrTkWT6lt8pqFxmGg0688qK8IWIKrurfgzTUtWMMWXhLQQ08Wa6/wACJyVUW9jgJdPCBp/A==

然后在 C# 中,我使用

C#1

var bytes = Encoding.UTF8.GetBytes(textToSign);
var data = new ContentInfo(bytes);
var signedCms = new SignedCms(data, true);
var signer = new CmsSigner(cert);
signedCms.ComputeSignature(signer);
var sign = signedCms.Encode();
var encodedSign = Convert.ToBase64String(sign);

C# 1 输出

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

C# 2

var sign = cert.GetRSAPrivateKey().SignData(bytes, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);

C# 2 输出

A1sSjgNMqSOQaElqHU1Mr0+aOqEwCFdhZAZzacFKs9dPGhUtR9I444YF5+422WJ+A7pd9wAlgejMflhF6lLr8ty/5pyy5BudNq4y1CIx7JSX87+7H1j2QIVIe1mPnKM1/IBD2g5IXDaTqt6S0QFVV9VRKjbe3fVCBo7hfV7gIo19nlBWi2eddEkOwUbqIDcfG/OpSeSkQvqxS/i215Cr3JpXnSSWRrB9ZDg956PI2j0nnAXnOZx/rYARy3btr+CXq1BHsCMclqEyjRZrrTkWT6lt8pqFxmGg0688qK8IWIKrurfgzTUtWMMWXhLQQ08Wa6/wACJyVUW9jgJdPCBp/A==

这与原始 C++ 输出非常相似。如果你比较它们,C#2Out 完全包含在 C++Out 中

我在这里做错了什么?

更新 1

C++ &signParameters

signParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
signParams.dwMsgEncodingType = MY_ENCODING_TYPE;
signParams.pSigningCert = certificate;
signParams.HashAlgorithm.pszObjId = (char *)szOID_OIWSEC_sha1;
signParams.HashAlgorithm.Parameters.cbData = NULL;
signParams.cMsgCert = 0;
signParams.rgpMsgCert = NULL;
signParams.cAuthAttr = 0;
signParams.dwInnerContentType = 0;
signParams.cMsgCrl = 0;
signParams.cUnauthAttr = 0;
signParams.dwFlags = 0;
signParams.pvHashAuxInfo = NULL;
signParams.rgAuthAttr = NULL;

更新 2

我最近注意到,无论使用 C++ 输入消息是什么,第一位总是相同的

MIIB8gYJKoZIhvcNAQcCoIIB4zCCAd8CAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGCAb4wggG6AgEBMIGWMH8xEjAQBgoJkiaJk/IsZAEZFgJhcjETMBEGCgmSJomT8ixkARkWA2NvbTEcMBoGCgmSJomT8ixkARkWDGJhbmNvZ2FsaWNpYTEVMBMGCgmSJomT8ixkARkWBWJnY216MR8wHQYDVQQDExZHYWxpY2lhIE9mZmljZSBDQS1TSEEyAhMbAAARQ28x78yrZlirAAEAABFDMAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEggEA

但我不知道他们来自哪里

【问题讨论】:

    标签: c# c++ cryptography


    【解决方案1】:

    我最终使用了 DllImport,look at this post

    我会复制到这里以防源被删除。

    using System;
    
    using System.Text;
    
    using System.ComponentModel;
    
    using System.Runtime.InteropServices;
    
    
    namespace ConsoleApplication1
    
    {
    
      class Class1
    
      {
    
        [STAThread]
    
        static void Main(string[] args)
    
        {
    
          // Parameters.
    
          //
    
          String sSignerName = "ALEJANDRO CAMPOS MAGENCIO";
    
          String sMessage = "CryptoAPI is a good way to handle security";
    
    
          // Variables.
    
          //
    
          Byte[] pbMessage = null;
    
          Int32 cbMessage = 0;
    
          IntPtr[] MessageArray = null;
    
          Int32[] MessageSizeArray = null;
    
          IntPtr hStoreHandle = IntPtr.Zero;
    
          IntPtr pSignerCert = IntPtr.Zero;
    
          Crypto.CRYPT_SIGN_MESSAGE_PARA SigParams;
    
          Boolean res = false;
    
          Int32 cbSignedMessageBlob = 0;
    
          Byte[] pbSignedMessageBlob = null;
    
          Crypto.CRYPT_VERIFY_MESSAGE_PARA VerifyParams;
    
          Int32 cbDecodedMessageBlob = 0;
    
          Byte[] pbDecodedMessageBlob = null;
    
    
          try
    
          {
    
            // Begin processing. Display the original message.
    
            //
    
            Console.WriteLine("-------------------------------------");
    
            Console.WriteLine("MESSAGE TO SIGN:\n");
    
            Console.WriteLine(sMessage + "\n\n");
    
    
            // Size of message.
    
            //
    
            pbMessage = (new UnicodeEncoding()).GetBytes(sMessage);
    
            cbMessage = pbMessage.Length;
    
    
            // Create the MessageArray and the MessageSizeArray.
    
            //
    
            MessageArray = new IntPtr[1];
    
            MessageArray[0] = Marshal.AllocHGlobal(pbMessage.Length);
    
            Marshal.Copy(pbMessage, 0, MessageArray[0], pbMessage.Length);
    
            MessageSizeArray = new Int32[1];
    
            MessageSizeArray[0] = cbMessage;
    
    
            // Open a certificate store.
    
            //
    
            hStoreHandle = Crypto.CertOpenStore(
    
              Crypto.CERT_STORE_PROV_SYSTEM,
    
              0,
    
              IntPtr.Zero,
    
              Crypto.CERT_SYSTEM_STORE_CURRENT_USER,
    
              Crypto.CERT_PERSONAL_STORE_NAME
    
            );
    
            if (hStoreHandle == IntPtr.Zero)
    
            {
    
              throw new Exception("CertOpenStore error", new Win32Exception(Marshal.GetLastWin32Error()));
    
            }
    
    
            // Get a pointer to the signer's certificate.
    
            // This certificate must have access to the signer's private key.
    
            pSignerCert = Crypto.CertFindCertificateInStore(
    
              hStoreHandle,
    
              Crypto.MY_TYPE,
    
              0,
    
              Crypto.CERT_FIND_SUBJECT_STR,
    
              sSignerName,
    
              IntPtr.Zero
    
            );
    
            if (pSignerCert == IntPtr.Zero)
    
            {
    
              throw new Exception("CertFindCertificateInStore error", new Win32Exception(Marshal.GetLastWin32Error()));
    
            }
    
    
            // Initialize the signature structure.
    
            //
    
            SigParams = new Crypto.CRYPT_SIGN_MESSAGE_PARA();
    
            SigParams.cbSize = Marshal.SizeOf(SigParams);
    
            SigParams.dwMsgEncodingType = Crypto.MY_TYPE;
    
            SigParams.pSigningCert = pSignerCert;
    
            SigParams.HashAlgorithm.pszObjId = Crypto.szOID_OIWSEC_sha1;
    
            SigParams.HashAlgorithm.Parameters.pbData = IntPtr.Zero;
    
            SigParams.HashAlgorithm.Parameters.cbData = 0;
    
            SigParams.pvHashAuxInfo = IntPtr.Zero;
    
            SigParams.cMsgCert = 1;
    
    
            GCHandle GC = GCHandle.Alloc(pSignerCert, GCHandleType.Pinned);
    
            SigParams.rgpMsgCert = GC.AddrOfPinnedObject();
    
            GC.Free();
    
    
            SigParams.cMsgCrl = 0;
    
            SigParams.rgpMsgCrl = IntPtr.Zero;
    
            SigParams.cAuthAttr = 0;
    
            SigParams.rgAuthAttr = IntPtr.Zero;
    
            SigParams.cUnauthAttr = 0;
    
            SigParams.rgUnauthAttr = IntPtr.Zero;
    
            SigParams.dwFlags = 0;
    
            SigParams.dwInnerContentType = 0;
    
    
            // With two calls to CryptSignMessage, sign the message.
    
            // First, get the size of the output signed BLOB.
    
            //
    
            res = Crypto.CryptSignMessage(
    
              ref SigParams,      // Signature parameters
    
              false,          // Not detached
    
              1,            // Number of messages
    
              MessageArray,      // Messages to be signed
    
              MessageSizeArray,    // Size of messages
    
              null,          // Buffer for signed message
    
              ref cbSignedMessageBlob  // Size of buffer
    
            );
    
            if (res == false)
    
            {
    
              throw new Exception("CryptSignMessage error", new Win32Exception(Marshal.GetLastWin32Error()));
    
            }
    
    
            // Allocate memory for the signed BLOB.
    
            //
    
            pbSignedMessageBlob = new Byte[cbSignedMessageBlob];
    
    
            // Get the SignedMessageBlob.
    
            //
    
            res = Crypto.CryptSignMessage(
    
              ref SigParams,      // Signature parameters
    
              false,          // Not detached
    
              1,            // Number of messages
    
              MessageArray,      // Messages to be signed
    
              MessageSizeArray,    // Size of messages
    
              pbSignedMessageBlob,  // Buffer for signed message
    
              ref cbSignedMessageBlob // Size of buffer
    
            );
    
            if (res == false)
    
            {
    
              throw new Exception("CryptSignMessage error", new Win32Exception(Marshal.GetLastWin32Error()));
    
            }
    
    
            // pbSignedMessageBlob points to the signed BLOB. Display the signature.
    
            //
    
            Console.WriteLine("-------------------------------------");
    
            Console.WriteLine("SIGNATURE:\n");
    
            Console.WriteLine(Convert.ToBase64String(pbSignedMessageBlob) + "\n\n");
    
    
            //  Verify the message signature. Usually, this
    
            //  would be done in a separate program.
    
            //
    
    
            //  Initialize the VerifyParams data structure.
    
            //
    
            VerifyParams = new Crypto.CRYPT_VERIFY_MESSAGE_PARA();
    
            VerifyParams.cbSize = Marshal.SizeOf(VerifyParams);
    
            VerifyParams.dwMsgAndCertEncodingType = Crypto.MY_TYPE;
    
            VerifyParams.hCryptProv = IntPtr.Zero;
    
            VerifyParams.pfnGetSignerCertificate = IntPtr.Zero;
    
            VerifyParams.pvGetArg = IntPtr.Zero;
    
    
            // With two calls to CryptVerifyMessageSignature, verify and decode
    
            // the signed message.
    
            // First, call CryptVerifyMessageSignature to get the length of the
    
            // buffer needed to hold the decoded message.
    
            //
    
            res = Crypto.CryptVerifyMessageSignature(
    
              ref VerifyParams,      // Verify parameters.
    
              0,              // Signer index.
    
              pbSignedMessageBlob,    // Pointer to signed BLOB.
    
              cbSignedMessageBlob,    // Size of signed BLOB.
    
              null,            // Buffer for decoded message.
    
              ref cbDecodedMessageBlob,  // Size of buffer.
    
              IntPtr.Zero          // Pointer to signer certificate.
    
            );
    
            if (res == false)
    
            {
    
              throw new Exception("CryptVerifyMessageSignature error", new Win32Exception(Marshal.GetLastWin32Error()));
    
            }
    
    
            //   Allocate memory for the buffer.
    
            //
    
            pbDecodedMessageBlob = new Byte[cbDecodedMessageBlob];
    
    
            //  Call CryptVerifyMessageSignature again to copy the message into
    
            //  the buffer.
    
            //
    
            res = Crypto.CryptVerifyMessageSignature(
    
              ref VerifyParams,      // Verify parameters.
    
              0,              // Signer index.
    
              pbSignedMessageBlob,    // Pointer to signed BLOB.
    
              cbSignedMessageBlob,    // Size of signed BLOB.
    
              pbDecodedMessageBlob,    // Buffer for decoded message.
    
              ref cbDecodedMessageBlob,  // Size of buffer.
    
              IntPtr.Zero          // Pointer to signer certificate.
    
            );
    
            if (res == false)
    
            {
    
              throw new Exception("CryptVerifyMessageSignature error", new Win32Exception(Marshal.GetLastWin32Error()));
    
            }
    
            else
    
            {
    
              // Display attached message to signature.
    
              //
    
              Console.WriteLine("-------------------------------------");
    
              Console.WriteLine("SIGNATURE VERIFIED!!!\n\n");
    
    
              Console.WriteLine("-------------------------------------");
    
              Console.WriteLine("ATTACHED MESSAGE:\n");
    
              Console.WriteLine((new UnicodeEncoding()).GetString(pbDecodedMessageBlob) + "\n\n");
    
            }
    
          }
    
          catch (Exception ex)
    
          {
    
            // Any errors? Show them.
    
            //
    
            if (ex.InnerException == null)
    
            {
    
              Console.WriteLine(ex.Message + "\n\n");
    
            }
    
            else
    
            {
    
              Console.WriteLine(ex.Message + " --> " + ex.InnerException.Message + "\n\n");
    
            }
    
          }
    
          finally
    
          {
    
            // Clean up and free memory.
    
            //
    
            if (MessageArray[0] != IntPtr.Zero)
    
            {
    
              Marshal.FreeHGlobal(MessageArray[0]);
    
            }
    
            if (pSignerCert != IntPtr.Zero)
    
            {
    
              Crypto.CertFreeCertificateContext(pSignerCert);
    
            }
    
            if (hStoreHandle != IntPtr.Zero)
    
            {
    
              Crypto.CertCloseStore(
    
                hStoreHandle,
    
                Crypto.CERT_CLOSE_STORE_CHECK_FLAG
    
              );
    
            }
    
          }
    
    
          Console.WriteLine("<<Press ENTER to continue>>" + "\n");
    
          Console.ReadLine();
    
        }
    
      }
    
    }
    

    using System;
    
    using System.Runtime.InteropServices;
    
    
    public class Crypto
    
    {
    
      #region CONSTS
    
    
      // #define CERT_PERSONAL_STORE_NAME      L"My"
    
      public const string CERT_PERSONAL_STORE_NAME = "My";
    
    
      // #define CERT_COMPARE_NAME   2
    
      public const Int32 CERT_COMPARE_NAME = 2;
    
    
      // #define CERT_INFO_SUBJECT_FLAG  7
    
      public const Int32 CERT_INFO_SUBJECT_FLAG = 7;
    
    
      // #define CERT_COMPARE_SHIFT        16
    
      public const Int32 CERT_COMPARE_SHIFT = 16;
    
    
      // #define CERT_FIND_SUBJECT_NAME    (CERT_COMPARE_NAME << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
    
      public const Int32 CERT_FIND_SUBJECT_NAME =
    
        (CERT_COMPARE_NAME << CERT_COMPARE_SHIFT) | CERT_INFO_SUBJECT_FLAG;
    
    
      // #define CERT_COMPARE_NAME_STR_W     8
    
      public const Int32 CERT_COMPARE_NAME_STR_W = 8;
    
    
      // #define CERT_FIND_SUBJECT_STR_W     //   (CERT_COMPARE_NAME_STR_W << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
    
      public const Int32 CERT_FIND_SUBJECT_STR_W =
    
        (CERT_COMPARE_NAME_STR_W << CERT_COMPARE_SHIFT) | CERT_INFO_SUBJECT_FLAG;
    
    
      // #define CERT_FIND_SUBJECT_STR CERT_FIND_SUBJECT_STR_W
    
      public const Int32 CERT_FIND_SUBJECT_STR = CERT_FIND_SUBJECT_STR_W;
    
    
      // #define CERT_STORE_PROV_SYSTEM_W      ((LPCSTR) 10)
    
      public const Int32 CERT_STORE_PROV_SYSTEM_W = 10;
    
    
      // #define CERT_STORE_PROV_SYSTEM        CERT_STORE_PROV_SYSTEM_W
    
      public const Int32 CERT_STORE_PROV_SYSTEM = CERT_STORE_PROV_SYSTEM_W;
    
    
      // #define CERT_SYSTEM_STORE_CURRENT_USER_ID     1
    
      public const Int32 CERT_SYSTEM_STORE_CURRENT_USER_ID = 1;
    
    
      // #define CERT_SYSTEM_STORE_LOCATION_SHIFT      16
    
      public const Int32 CERT_SYSTEM_STORE_LOCATION_SHIFT = 16;
    
    
      // #define CERT_SYSTEM_STORE_CURRENT_USER          //   (CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT)
    
      public const Int32 CERT_SYSTEM_STORE_CURRENT_USER =
    
        CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT;
    
    
      // #define CERT_CLOSE_STORE_CHECK_FLAG       0x00000002
    
      public const Int32 CERT_CLOSE_STORE_CHECK_FLAG = 0x00000002;
    
    
      // #define ALG_CLASS_HASH                  (4 << 13)
    
      // #define ALG_TYPE_ANY                    (0)
    
      // #define ALG_SID_SHA1                    4
    
      // #define CALG_SHA1               (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA1)
    
      public const Int32 CALG_SHA1 = (4 << 13) | 4;
    
    
      // #define ALG_CLASS_SIGNATURE             (1 << 13)
    
      // #define ALG_TYPE_RSA                    (2 << 9)
    
      // #define ALG_SID_RSA_ANY                 0
    
      // #define CALG_RSA_SIGN           (ALG_CLASS_SIGNATURE | ALG_TYPE_RSA | ALG_SID_RSA_ANY)
    
      public const Int32 CALG_RSA_SIGN = (1 << 13) | (2 << 9);
    
    
      // #define PROV_RSA_FULL           1
    
      public const Int32 PROV_RSA_FULL = 0x00000001;
    
    
      // #define CRYPT_VERIFYCONTEXT     0xF0000000
    
      public const UInt32 CRYPT_VERIFYCONTEXT = 0xF0000000; //No private key access required
    
    
      // #define X509_ASN_ENCODING           0x00000001
    
      public const Int32 X509_ASN_ENCODING = 0x00000001;
    
    
      // #define PKCS_7_ASN_ENCODING         0x00010000
    
      public const Int32 PKCS_7_ASN_ENCODING = 0x00010000;
    
    
      // #define MY_TYPE       (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
    
      public const Int32 MY_TYPE = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
    
    
      // #define HP_HASHVAL              0x0002
    
      public const Int32 HP_HASHVAL = 0x00000002;
    
    
      // #define HP_HASHSIZE             0x0004
    
      public const Int32 HP_HASHSIZE = 0x00000004;
    
    
      // #define PUBLICKEYBLOBEX 0xA
    
      public const Int32 PUBLICKEYBLOBEX = 0x0A;
    
    
      // #define PUBLICKEYBLOB           0x6
    
      public const Int32 PUBLICKEYBLOB = 0x06;
    
    
      // #define CUR_BLOB_VERSION 0x02
    
      public const Int32 CUR_BLOB_VERSION = 0x02;
    
    
      // #define CRYPT_EXPORTABLE        0x00000001
    
      public const Int32 CRYPT_EXPORTABLE = 0x00000001;
    
    
      // #define szOID_RSA_MD5           "1.2.840.113549.2.5"
    
      public const String szOID_RSA_MD5 = "1.2.840.113549.2.5";
    
    
      // #define szOID_RSA_MD5RSA        "1.2.840.113549.1.1.4"
    
      public const String szOID_RSA_MD5RSA = "1.2.840.113549.1.1.4";
    
    
      // #define szOID_OIWSEC_sha1       "1.3.14.3.2.26"
    
      public const String szOID_OIWSEC_sha1 = "1.3.14.3.2.26";
    
    
      #endregion
    
    
      #region STRUCTS
    
    
      // typedef struct _PUBLICKEYSTRUC
    
      // {
    
      //    BYTE bType;
    
      //    BYTE bVersion;
    
      //    WORD reserved;
    
      //    ALG_ID aiKeyAlg;
    
      // } BLOBHEADER, PUBLICKEYSTRUC;
    
      [StructLayout(LayoutKind.Sequential)]
    
      public struct PUBLICKEYSTRUC
    
      {
    
        public Byte bType;
    
        public Byte bVersion;
    
        public Int16 reserved;
    
        public Int32 aiKeyAlg;
    
      }
    
    
      // typedef struct _RSAPUBKEY
    
      // {
    
      //    DWORD magic;
    
      //    DWORD bitlen;
    
      //    DWORD pubexp;
    
      // } RSAPUBKEY;
    
      [StructLayout(LayoutKind.Sequential)]
    
      public struct RSAPUBKEY
    
      {
    
        public Int32 magic;
    
        public Int32 bitlen;
    
        public Int32 pubexp;
    
      }
    
    
      // typedef struct _CRYPTOAPI_BLOB
    
      // {
    
      //    DWORD   cbData;
    
      //    BYTE    *pbData;
    
      // } CRYPT_HASH_BLOB, CRYPT_INTEGER_BLOB,
    
      //   CRYPT_OBJID_BLOB, CERT_NAME_BLOB;
    
      [StructLayout(LayoutKind.Sequential)]
    
      public struct CRYPTOAPI_BLOB
    
      {
    
        public Int32 cbData;
    
        public IntPtr pbData;
    
      }
    
    
      // typedef struct _CRYPT_ALGORITHM_IDENTIFIER
    
      // {
    
      //    LPSTR pszObjId;
    
      //    CRYPT_OBJID_BLOB Parameters;
    
      // } CRYPT_ALGORITHM_IDENTIFIER;
    
      [StructLayout(LayoutKind.Sequential)]
    
      public struct CRYPT_ALGORITHM_IDENTIFIER
    
      {
    
        [MarshalAs(UnmanagedType.LPStr)]public String pszObjId;
    
        public CRYPTOAPI_BLOB Parameters;
    
      }
    
    
      // typedef struct _CRYPT_SIGN_MESSAGE_PARA
    
      // {
    
      //    DWORD cbSize;
    
      //    DWORD dwMsgEncodingType;
    
      //    PCCERT_CONTEXT pSigningCert;
    
      //    CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
    
      //    void *pvHashAuxInfo;
    
      //    DWORD cMsgCert;
    
      //    PCCERT_CONTEXT *rgpMsgCert;
    
      //    DWORD cMsgCrl;
    
      //    PCCRL_CONTEXT *rgpMsgCrl;
    
      //    DWORD cAuthAttr;
    
      //    PCRYPT_ATTRIBUTE rgAuthAttr;
    
      //    DWORD cUnauthAttr;
    
      //    PCRYPT_ATTRIBUTE rgUnauthAttr;
    
      //    DWORD dwFlags;
    
      //    DWORD dwInnerContentType;
    
      // } CRYPT_SIGN_MESSAGE_PARA;
    
      [StructLayout(LayoutKind.Sequential)]
    
      public struct CRYPT_SIGN_MESSAGE_PARA
    
      {
    
        public Int32 cbSize;
    
        public Int32 dwMsgEncodingType;
    
        public IntPtr pSigningCert;
    
        public CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
    
        public IntPtr pvHashAuxInfo;
    
        public Int32 cMsgCert;
    
        public IntPtr rgpMsgCert;
    
        public Int32 cMsgCrl;
    
        public IntPtr rgpMsgCrl;
    
        public Int32 cAuthAttr;
    
        public IntPtr rgAuthAttr;
    
        public Int32 cUnauthAttr;
    
        public IntPtr rgUnauthAttr;
    
        public Int32 dwFlags;
    
        public Int32 dwInnerContentType;
    
      }
    
    
      // typedef struct _CRYPT_VERIFY_MESSAGE_PARA
    
      // {
    
      //    DWORD cbSize;
    
      //    DWORD dwMsgAndCertEncodingType;
    
      //    HCRYPTPROV hCryptProv;
    
      //    PFN_CRYPT_GET_SIGNER_CERTIFICATE pfnGetSignerCertificate;
    
      //    void *pvGetArg;
    
      // } CRYPT_VERIFY_MESSAGE_PARA;
    
      [StructLayout(LayoutKind.Sequential)]
    
      public struct CRYPT_VERIFY_MESSAGE_PARA
    
      {
    
        public Int32 cbSize;
    
        public Int32 dwMsgAndCertEncodingType;
    
        public IntPtr hCryptProv;
    
        public IntPtr pfnGetSignerCertificate;
    
        public IntPtr pvGetArg;
    
      }
    
    
      #endregion
    
    
      #region FUNCTIONS (IMPORTS)
    
    
      [DllImport("Crypt32.dll", CharSet=CharSet.Auto, SetLastError=true)]
    
      public static extern IntPtr CertOpenStore(
    
        Int32 lpszStoreProvider,
    
        Int32 dwMsgAndCertEncodingType,
    
        IntPtr hCryptProv,
    
        Int32 dwFlags,
    
        String pvPara
    
      ); 
    
    
      [DllImport("Crypt32.dll", CharSet=CharSet.Auto, SetLastError=true)]
    
      public static extern IntPtr CertOpenSystemStore(
    
        IntPtr hprov,
    
        String szSubsystemProtocol
    
      );
    
    
      [DllImport("Crypt32.dll", SetLastError=true)]
    
      public static extern Boolean CertCloseStore(
    
        IntPtr hCertStore,
    
        Int32 dwFlags
    
      );    
    
    
      [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
    
      public static extern bool CryptAcquireContext(
    
        ref IntPtr hProv,
    
        String pszContainer,
    
        String pszProvider,
    
        Int32 dwProvType,
    
        Int32 dwFlags
    
      );
    
    
      [DllImport("advapi32.dll", SetLastError=true)]
    
      public static extern bool CryptCreateHash(
    
        IntPtr hProv,
    
        Int32 Algid,
    
        IntPtr hKey,
    
        Int32 dwFlags,
    
        ref IntPtr phHash
    
      );
    
    
      [DllImport("advapi32.dll", SetLastError=true)]
    
      public static extern bool CryptGetHashParam(
    
        IntPtr hHash,
    
        Int32 dwParam,
    
        ref Int32 pbData,
    
        ref Int32 pdwDataLen,
    
        Int32 dwFlags
    
      );
    
    
      [DllImport("advapi32.dll", SetLastError=true)]
    
      public static extern bool CryptSetHashParam(
    
        IntPtr hHash,
    
        Int32 dwParam,
    
        Byte[] pbData,
    
        Int32 dwFlags
    
      );
    
    
      [DllImport("crypt32.dll", CharSet=CharSet.Auto, SetLastError=true)]
    
      public static extern bool CryptImportPublicKeyInfo(
    
        IntPtr hCryptProv,
    
        Int32 dwCertEncodingType,
    
        IntPtr pInfo,
    
        ref IntPtr phKey
    
      );
    
    
      [DllImport("advapi32.dll", SetLastError=true)]
    
      public static extern bool CryptImportKey(
    
        IntPtr hProv,
    
        Byte[] pbData,
    
        Int32 dwDataLen,
    
        IntPtr hPubKey,
    
        Int32 dwFlags,
    
        ref IntPtr phKey
    
      );
    
    
      [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
    
      public static extern bool CryptVerifySignature(
    
        IntPtr hHash,
    
        Byte[] pbSignature,
    
        Int32 dwSigLen,
    
        IntPtr hPubKey,
    
        String sDescription,
    
        Int32 dwFlags
    
      );
    
    
      [DllImport("advapi32.dll", SetLastError=true)]
    
      public static extern bool CryptDestroyKey(
    
        IntPtr hKey
    
      );
    
    
      [DllImport("advapi32.dll", SetLastError=true)]
    
      public static extern bool CryptDestroyHash(
    
        IntPtr hHash
    
      );
    
    
      [DllImport("advapi32.dll", SetLastError=true)]
    
      public static extern bool CryptReleaseContext(
    
        IntPtr hProv,
    
        Int32 dwFlags
    
      );
    
    
      [DllImport("advapi32.dll", SetLastError=true)]
    
      public static extern bool CryptGenKey(
    
        IntPtr hProv,
    
        Int32 Algid,
    
        Int32 dwFlags,
    
        ref IntPtr phKey
    
      );
    
    
      [DllImport("advapi32.dll", SetLastError=true)]
    
      public static extern bool CryptExportKey(
    
        IntPtr hKey,
    
        IntPtr hExpKey,
    
        Int32 dwBlobType,
    
        Int32 dwFlags,
    
        Byte[] pbData,
    
        ref Int32 pdwDataLen
    
      );
    
    
      [DllImport("Crypt32.dll", CharSet=CharSet.Auto, SetLastError=true)]
    
      public static extern IntPtr CertFindCertificateInStore(
    
        IntPtr hCertStore,
    
        Int32 dwCertEncodingType,
    
        Int32 dwFindFlags,
    
        Int32 dwFindType,
    
        String pvFindPara,
    
        IntPtr pPrevCertContext
    
      );
    
    
      [DllImport("Crypt32.dll", SetLastError=true)]
    
      public static extern Boolean CertFreeCertificateContext(
    
        IntPtr pCertContext
    
      );
    
    
      [DllImport("Crypt32.dll", SetLastError=true)]
    
      public static extern Boolean CryptSignMessage (
    
        ref CRYPT_SIGN_MESSAGE_PARA pSignPara,
    
        Boolean fDetachedSignature,
    
        Int32 cToBeSigned,
    
        IntPtr[] rgpbToBeSigned,
    
        Int32[] rgcbToBeSigned,
    
        Byte[] pbSignedBlob,
    
        ref Int32 pcbSignedBlob
    
      );
    
    
      [DllImport("Crypt32.dll", SetLastError=true)]
    
      public static extern Boolean CryptVerifyMessageSignature (
    
        ref CRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
    
        Int32 dwSignerIndex,
    
        Byte[] pbSignedBlob,
    
        Int32 cbSignedBlob,
    
        Byte[] pbDecoded,
    
        ref Int32 pcbDecoded,
    
        IntPtr ppSignerCert
    
      );
    
    
      #endregion 
    
    
      #region FUNTIONS
    
    
      // Helper function to convert struts & classes to byte array
    
      public static byte[] RawSerialize(object anything)
    
      {
    
        int rawsize = Marshal.SizeOf(anything);
    
        IntPtr buffer = Marshal.AllocHGlobal(rawsize);
    
        Marshal.StructureToPtr(anything, buffer, false);
    
        byte[] rawdatas = new byte[rawsize];
    
        Marshal.Copy(buffer, rawdatas, 0, rawsize);
    
        Marshal.FreeHGlobal(buffer);
    
        return rawdatas;
    
      } 
    
    
      #endregion
    
    
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-15
      • 1970-01-01
      • 1970-01-01
      • 2011-03-13
      • 2011-09-28
      • 1970-01-01
      • 2015-08-04
      • 2010-10-13
      • 1970-01-01
      相关资源
      最近更新 更多