c# - 将C++ Pkcs7符号移植到C#

标签 c# c++ cryptography

由于维护原因,我正在将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

但是我不知道它们来自哪里

最佳答案

我最终使用了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


}

关于c# - 将C++ Pkcs7符号移植到C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62328665/

相关文章:

c# - 如何在 ubuntu/linux 上运行 asmx webservice?

c# - 错误 "string parameter too long"。在 microsoft.office.interop.word.find.execute

c++ - 在 C++ 中重载二元关系运算符的正确方法

c++ - 图 - 强连通分量

c# - 带有枚举角色参数的自定义 AuthorizeAttributte 在 ajax 调用中获取空值

c# - 将属性附加到对象

c++ - 你如何在 win32 中的 WM_CREATE 消息之外创建一个按钮?

java - 如何读取用于 OpenSAML 的私钥?

swift - Swift 中的 secp256k1 公钥解析

cryptography - 如何破译未知的替换密码