如何使用.net读取PKCS12格式数字证书

 

随着《电子签名法》的颁布,数字证书应用越来越广泛,在一般的应用中,我们都是在系统中安装pkcs12格式的证书。在访问应用(一般是网页、电子邮件等)时,选择合适的证书。我们也可以使用编程来直接读取证书文件。下面我们就介绍如何使用.net读取数字证书。

 

要读取 pkcs12 格式的证书,我们需要调用 API ,在 WIN32 类中,我们声明这些 API 的引用:

 1 None.gif using  System;
 2 None.gif using  System.Runtime.InteropServices;
 3 None.gif
 4 None.gif namespace  X509Cert
 5 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 6InBlock.gif
 7InBlock.gif    public class WIN32
 8ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 9InBlock.gif        public const uint CRYPT_USER_KEYSET = 0x00001000;
10InBlock.gif        public const uint CERT_KEY_PROV_INFO_PROP_ID = 0x00000002;
11InBlock.gif        public const uint CRYPT_DELETEKEYSET   = 0x00000010;
12InBlock.gif
13InBlock.gif        [DllImport("crypt32.dll", SetLastError=true)]   
14InBlock.gif        public static extern IntPtr PFXImportCertStore(ref CRYPT_DATA_BLOB pPfx,[MarshalAs(UnmanagedType.LPWStr)] String szPassword,uint dwFlags);
15InBlock.gif
16InBlock.gif        [DllImport("CRYPT32.DLL", EntryPoint="CertEnumCertificatesInStore", CharSet=CharSet.Auto, SetLastError=true)]
17InBlock.gif        public static extern IntPtr CertEnumCertificatesInStore( IntPtr storeProvider, IntPtr prevCertContext);
18InBlock.gif
19InBlock.gif        [DllImport("CRYPT32.DLL",CharSet=CharSet.Auto, SetLastError=true)]
20InBlock.gif        public static extern bool CertGetCertificateContextProperty(IntPtr pCertContext,uint dwPropId,IntPtr pvData,ref uint pcbData);
21InBlock.gif
22InBlock.gif        [DllImport("advapi32.dll",EntryPoint="CryptAcquireContext",CharSet=CharSet.Auto, SetLastError=true)]
23InBlock.gif        public static extern bool CryptAcquireContext(ref IntPtr phProv,string szContainer,string szProvider,uint dwProvType,uint dwFlags);
24InBlock.gif
25InBlock.gif        [StructLayout(LayoutKind.Sequential)]
26ExpandedSubBlockStart.gifContractedSubBlock.gif        public struct CRYPT_DATA_BLOB dot.gif{
27InBlock.gif            public int cbData;
28InBlock.gif            public IntPtr pbData;
29ExpandedSubBlockEnd.gif        }

30InBlock.gif
31InBlock.gif        [StructLayout(LayoutKind.Sequential)]
32ExpandedSubBlockStart.gifContractedSubBlock.gif        public struct CRYPT_KEY_PROV_INFO dot.gif{
33InBlock.gif
34InBlock.gif            [MarshalAs(UnmanagedType.LPWStr)] 
35InBlock.gif            public String ContainerName;
36InBlock.gif
37InBlock.gif            [MarshalAs(UnmanagedType.LPWStr)] 
38InBlock.gif            public String ProvName;
39InBlock.gif
40InBlock.gif            public uint ProvType;
41InBlock.gif
42InBlock.gif            public uint Flags;
43InBlock.gif
44InBlock.gif            public uint ProvParam;
45InBlock.gif
46InBlock.gif            public IntPtr rgProvParam;
47InBlock.gif
48InBlock.gif            public uint KeySpec;
49InBlock.gif
50ExpandedSubBlockEnd.gif        }

51InBlock.gif
52InBlock.gif        public WIN32()
53ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
54InBlock.gif            //
55InBlock.gif            // TODO: 在此处添加构造函数逻辑
56InBlock.gif            //
57ExpandedSubBlockEnd.gif        }

58ExpandedSubBlockEnd.gif    }

59ExpandedBlockEnd.gif}

60 None.gif

 

 

然后在Cert类中写一个Read方法读取其中的证书。注意:pfx文件有可能包含几个证书

 1 None.gif using  System;
 2 None.gif using  System.IO;
 3 None.gif using  System.Runtime.InteropServices;
 4 None.gif using  System.Security.Cryptography.X509Certificates;
 5 None.gif
 6 None.gif namespace  X509Cert
 7 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 8ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
 9InBlock.gif    /// Cert 的摘要说明。
10ExpandedSubBlockEnd.gif    /// </summary>

11InBlock.gif    public class Cert
12ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
13InBlock.gif        public Cert()
14ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
15InBlock.gif            //
16InBlock.gif            // TODO: 在此处添加构造函数逻辑
17InBlock.gif            //
18ExpandedSubBlockEnd.gif        }

19ExpandedSubBlockStart.gifContractedSubBlock.gif        public static System.Security.Cryptography.X509Certificates.X509Certificate[] Read(string filename,string password) dot.gif{
20InBlock.gif
21InBlock.gif            //打开证书文件,并读到一个字节数组中。
22InBlock.gif            FileStream stream = new FileStream(filename,FileMode.Open);
23InBlock.gif            byte[] buffer = new byte[stream.Length];
24InBlock.gif            stream.Read(buffer,0,buffer.Length);
25InBlock.gif            stream.Close();          
26InBlock.gif
27InBlock.gif            //声明并实例化WIN32.CRYPT_DATA_BLOB 将读取到的字节数组拷贝到它的pbData属性中。将字节数组长度赋给cbData属性
28InBlock.gif            WIN32.CRYPT_DATA_BLOB cryptdata = new WIN32.CRYPT_DATA_BLOB();
29InBlock.gif            cryptdata.cbData = buffer.Length;
30InBlock.gif            cryptdata.pbData = Marshal.AllocHGlobal(cryptdata.cbData);
31InBlock.gif            Marshal.Copy(buffer,0,cryptdata.pbData,buffer.Length);
32InBlock.gif            IntPtr hMemStore = WIN32.PFXImportCertStore(ref cryptdata,"1234",WIN32.CRYPT_USER_KEYSET);
33InBlock.gif            Marshal.FreeHGlobal(cryptdata.pbData);
34InBlock.gif
35InBlock.gif            uint provinfosize = 0;
36InBlock.gif            WIN32.CRYPT_KEY_PROV_INFO certinfo = new WIN32.CRYPT_KEY_PROV_INFO();
37InBlock.gif
38InBlock.gif            System.Collections.ArrayList certs = new System.Collections.ArrayList();
39InBlock.gif
40InBlock.gif            IntPtr certHandle = IntPtr.Zero;
41ExpandedSubBlockStart.gifContractedSubBlock.gif            while((certHandle = WIN32.CertEnumCertificatesInStore(hMemStore,certHandle)) != IntPtr.Zero) dot.gif{
42InBlock.gif
43ExpandedSubBlockStart.gifContractedSubBlock.gif                if(WIN32.CertGetCertificateContextProperty(certHandle,WIN32.CERT_KEY_PROV_INFO_PROP_ID,IntPtr.Zero,ref provinfosize))dot.gif{
44InBlock.gif
45InBlock.gif                    IntPtr info = Marshal.AllocHGlobal((int)provinfosize);
46InBlock.gif
47ExpandedSubBlockStart.gifContractedSubBlock.gif                    if(WIN32.CertGetCertificateContextProperty(certHandle,WIN32.CERT_KEY_PROV_INFO_PROP_ID,info,ref provinfosize)) dot.gif{
48InBlock.gif                        certinfo = (WIN32.CRYPT_KEY_PROV_INFO)Marshal.PtrToStructure(info,typeof(WIN32.CRYPT_KEY_PROV_INFO));    
49InBlock.gif
50InBlock.gif                        certs.Add(new X509Certificate(certHandle));
51ExpandedSubBlockEnd.gif                    }

52InBlock.gif                    Marshal.FreeHGlobal(info);
53InBlock.gif
54ExpandedSubBlockEnd.gif                }

55ExpandedSubBlockEnd.gif            }

56InBlock.gif
57InBlock.gif            Marshal.FreeHGlobal(hMemStore);
58InBlock.gif
59InBlock.gif            IntPtr hCryptProv = IntPtr.Zero;
60InBlock.gif            if(!WIN32.CryptAcquireContext(ref hCryptProv,certinfo.ContainerName,certinfo.ProvName,certinfo.ProvType,WIN32.CRYPT_DELETEKEYSET))
61InBlock.gif                throw new Exception("释放内存错误");
62InBlock.gif            return (X509Certificate[])certs.ToArray(typeof(X509Certificate));
63InBlock.gif     
64ExpandedSubBlockEnd.gif        }

65ExpandedSubBlockEnd.gif    }

66ExpandedBlockEnd.gif}

67 None.gif

 

 

转载于:https://www.cnblogs.com/rainlake/archive/2005/09/15/237997.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值