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