.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));
}
}
}

浙公网安备 33010602011771号