.net调用WIN32 API 读取PKCS12格式数字证书
COPY FROM http://www.cnblogs.com/rainlake/archive/2005/09/15/237997.html
using System; using System.Runtime.InteropServices; namespace X509Cert { public class WIN32 { public const uint CRYPT_USER_KEYSET = 0x00001000; public const uint CERT_KEY_PROV_INFO_PROP_ID = 0x00000002; public const uint CRYPT_DELETEKEYSET = 0x00000010; [DllImport("crypt32.dll", SetLastError=true)] public static extern IntPtr PFXImportCertStore(ref CRYPT_DATA_BLOB pPfx,[MarshalAs(UnmanagedType.LPWStr)] String szPassword,uint dwFlags); [DllImport("CRYPT32.DLL", EntryPoint="CertEnumCertificatesInStore", CharSet=CharSet.Auto, SetLastError=true)] public static extern IntPtr CertEnumCertificatesInStore( IntPtr storeProvider, IntPtr prevCertContext); [DllImport("CRYPT32.DLL",CharSet=CharSet.Auto, SetLastError=true)] public static extern bool CertGetCertificateContextProperty(IntPtr pCertContext,uint dwPropId,IntPtr pvData,ref uint pcbData); [DllImport("advapi32.dll",EntryPoint="CryptAcquireContext",CharSet=CharSet.Auto, SetLastError=true)] public static extern bool CryptAcquireContext(ref IntPtr phProv,string szContainer,string szProvider,uint dwProvType,uint dwFlags); [StructLayout(LayoutKind.Sequential)] public struct CRYPT_DATA_BLOB { public int cbData; public IntPtr pbData; } [StructLayout(LayoutKind.Sequential)] public struct CRYPT_KEY_PROV_INFO { [MarshalAs(UnmanagedType.LPWStr)] public String ContainerName; [MarshalAs(UnmanagedType.LPWStr)] public String ProvName; public uint ProvType; public uint Flags; public uint ProvParam; public IntPtr rgProvParam; public uint KeySpec; } public WIN32() { // // TODO: 在此处添加构造函数逻辑 // } } } using System; using System.IO; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; namespace X509Cert { /// <summary> /// Cert 的摘要说明。 /// </summary> public class Cert { public Cert() { // // TODO: 在此处添加构造函数逻辑 // } public static System.Security.Cryptography.X509Certificates.X509Certificate[] Read(string filename,string password) { //打开证书文件,并读到一个字节数组中。 FileStream stream = new FileStream(filename,FileMode.Open); byte[] buffer = new byte[stream.Length]; stream.Read(buffer,0,buffer.Length); stream.Close(); //声明并实例化WIN32.CRYPT_DATA_BLOB 将读取到的字节数组拷贝到它的pbData属性中。将字节数组长度赋给cbData属性 WIN32.CRYPT_DATA_BLOB cryptdata = new WIN32.CRYPT_DATA_BLOB(); cryptdata.cbData = buffer.Length; cryptdata.pbData = Marshal.AllocHGlobal(cryptdata.cbData); Marshal.Copy(buffer,0,cryptdata.pbData,buffer.Length); IntPtr hMemStore = WIN32.PFXImportCertStore(ref cryptdata,"1234",WIN32.CRYPT_USER_KEYSET); Marshal.FreeHGlobal(cryptdata.pbData); uint provinfosize = 0; WIN32.CRYPT_KEY_PROV_INFO certinfo = new WIN32.CRYPT_KEY_PROV_INFO(); System.Collections.ArrayList certs = new System.Collections.ArrayList(); IntPtr certHandle = IntPtr.Zero; while((certHandle = WIN32.CertEnumCertificatesInStore(hMemStore,certHandle)) != IntPtr.Zero) { if(WIN32.CertGetCertificateContextProperty(certHandle,WIN32.CERT_KEY_PROV_INFO_PROP_ID,IntPtr.Zero,ref provinfosize)){ IntPtr info = Marshal.AllocHGlobal((int)provinfosize); if(WIN32.CertGetCertificateContextProperty(certHandle,WIN32.CERT_KEY_PROV_INFO_PROP_ID,info,ref provinfosize)) { certinfo = (WIN32.CRYPT_KEY_PROV_INFO)Marshal.PtrToStructure(info,typeof(WIN32.CRYPT_KEY_PROV_INFO)); certs.Add(new X509Certificate(certHandle)); } Marshal.FreeHGlobal(info); } } Marshal.FreeHGlobal(hMemStore); IntPtr hCryptProv = IntPtr.Zero; if(!WIN32.CryptAcquireContext(ref hCryptProv,certinfo.ContainerName,certinfo.ProvName,certinfo.ProvType,WIN32.CRYPT_DELETEKEYSET)) throw new Exception("释放内存错误"); return (X509Certificate[])certs.ToArray(typeof(X509Certificate)); } } }