如何使用.net读取PKCS12格式数字证书
随着《电子签名法》的颁布,数字证书应用越来越广泛,在一般的应用中,我们都是在系统中安装pkcs12格式的证书。在访问应用(一般是网页、电子邮件等)时,选择合适的证书。我们也可以使用编程来直接读取证书文件。下面我们就介绍如何使用.net读取数字证书。
要读取pkcs12格式的证书,我们需要调用API,在WIN32类中,我们声明这些API的引用:
1
using System;
2
using System.Runtime.InteropServices;
3![](/Images/OutliningIndicators/None.gif)
4
namespace X509Cert
5
{
6![](/Images/OutliningIndicators/InBlock.gif)
7
public class WIN32
8
{
9
public const uint CRYPT_USER_KEYSET = 0x00001000;
10
public const uint CERT_KEY_PROV_INFO_PROP_ID = 0x00000002;
11
public const uint CRYPT_DELETEKEYSET = 0x00000010;
12![](/Images/OutliningIndicators/InBlock.gif)
13
[DllImport("crypt32.dll", SetLastError=true)]
14
public static extern IntPtr PFXImportCertStore(ref CRYPT_DATA_BLOB pPfx,[MarshalAs(UnmanagedType.LPWStr)] String szPassword,uint dwFlags);
15![](/Images/OutliningIndicators/InBlock.gif)
16
[DllImport("CRYPT32.DLL", EntryPoint="CertEnumCertificatesInStore", CharSet=CharSet.Auto, SetLastError=true)]
17
public static extern IntPtr CertEnumCertificatesInStore( IntPtr storeProvider, IntPtr prevCertContext);
18![](/Images/OutliningIndicators/InBlock.gif)
19
[DllImport("CRYPT32.DLL",CharSet=CharSet.Auto, SetLastError=true)]
20
public static extern bool CertGetCertificateContextProperty(IntPtr pCertContext,uint dwPropId,IntPtr pvData,ref uint pcbData);
21![](/Images/OutliningIndicators/InBlock.gif)
22
[DllImport("advapi32.dll",EntryPoint="CryptAcquireContext",CharSet=CharSet.Auto, SetLastError=true)]
23
public static extern bool CryptAcquireContext(ref IntPtr phProv,string szContainer,string szProvider,uint dwProvType,uint dwFlags);
24![](/Images/OutliningIndicators/InBlock.gif)
25
[StructLayout(LayoutKind.Sequential)]
26
public struct CRYPT_DATA_BLOB {
27
public int cbData;
28
public IntPtr pbData;
29
}
30![](/Images/OutliningIndicators/InBlock.gif)
31
[StructLayout(LayoutKind.Sequential)]
32
public struct CRYPT_KEY_PROV_INFO {
33![](/Images/OutliningIndicators/InBlock.gif)
34
[MarshalAs(UnmanagedType.LPWStr)]
35
public String ContainerName;
36![](/Images/OutliningIndicators/InBlock.gif)
37
[MarshalAs(UnmanagedType.LPWStr)]
38
public String ProvName;
39![](/Images/OutliningIndicators/InBlock.gif)
40
public uint ProvType;
41![](/Images/OutliningIndicators/InBlock.gif)
42
public uint Flags;
43![](/Images/OutliningIndicators/InBlock.gif)
44
public uint ProvParam;
45![](/Images/OutliningIndicators/InBlock.gif)
46
public IntPtr rgProvParam;
47![](/Images/OutliningIndicators/InBlock.gif)
48
public uint KeySpec;
49![](/Images/OutliningIndicators/InBlock.gif)
50
}
51![](/Images/OutliningIndicators/InBlock.gif)
52
public WIN32()
53
{
54
//
55
// TODO: 在此处添加构造函数逻辑
56
//
57
}
58
}
59
}
60![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/None.gif)
5
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
6
![](/Images/OutliningIndicators/InBlock.gif)
7
![](/Images/OutliningIndicators/InBlock.gif)
8
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
9
![](/Images/OutliningIndicators/InBlock.gif)
10
![](/Images/OutliningIndicators/InBlock.gif)
11
![](/Images/OutliningIndicators/InBlock.gif)
12
![](/Images/OutliningIndicators/InBlock.gif)
13
![](/Images/OutliningIndicators/InBlock.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/InBlock.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/InBlock.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/InBlock.gif)
24
![](/Images/OutliningIndicators/InBlock.gif)
25
![](/Images/OutliningIndicators/InBlock.gif)
26
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
27
![](/Images/OutliningIndicators/InBlock.gif)
28
![](/Images/OutliningIndicators/InBlock.gif)
29
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
30
![](/Images/OutliningIndicators/InBlock.gif)
31
![](/Images/OutliningIndicators/InBlock.gif)
32
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
33
![](/Images/OutliningIndicators/InBlock.gif)
34
![](/Images/OutliningIndicators/InBlock.gif)
35
![](/Images/OutliningIndicators/InBlock.gif)
36
![](/Images/OutliningIndicators/InBlock.gif)
37
![](/Images/OutliningIndicators/InBlock.gif)
38
![](/Images/OutliningIndicators/InBlock.gif)
39
![](/Images/OutliningIndicators/InBlock.gif)
40
![](/Images/OutliningIndicators/InBlock.gif)
41
![](/Images/OutliningIndicators/InBlock.gif)
42
![](/Images/OutliningIndicators/InBlock.gif)
43
![](/Images/OutliningIndicators/InBlock.gif)
44
![](/Images/OutliningIndicators/InBlock.gif)
45
![](/Images/OutliningIndicators/InBlock.gif)
46
![](/Images/OutliningIndicators/InBlock.gif)
47
![](/Images/OutliningIndicators/InBlock.gif)
48
![](/Images/OutliningIndicators/InBlock.gif)
49
![](/Images/OutliningIndicators/InBlock.gif)
50
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
51
![](/Images/OutliningIndicators/InBlock.gif)
52
![](/Images/OutliningIndicators/InBlock.gif)
53
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
54
![](/Images/OutliningIndicators/InBlock.gif)
55
![](/Images/OutliningIndicators/InBlock.gif)
56
![](/Images/OutliningIndicators/InBlock.gif)
57
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
58
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
59
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
60
![](/Images/OutliningIndicators/None.gif)
然后在Cert类中写一个Read方法读取其中的证书。注意:pfx文件有可能包含几个证书
1
using System;
2
using System.IO;
3
using System.Runtime.InteropServices;
4
using System.Security.Cryptography.X509Certificates;
5![](/Images/OutliningIndicators/None.gif)
6
namespace X509Cert
7
{
8
/// <summary>
9
/// Cert 的摘要说明。
10
/// </summary>
11
public class Cert
12
{
13
public Cert()
14
{
15
//
16
// TODO: 在此处添加构造函数逻辑
17
//
18
}
19
public static System.Security.Cryptography.X509Certificates.X509Certificate[] Read(string filename,string password) {
20![](/Images/OutliningIndicators/InBlock.gif)
21
//打开证书文件,并读到一个字节数组中。
22
FileStream stream = new FileStream(filename,FileMode.Open);
23
byte[] buffer = new byte[stream.Length];
24
stream.Read(buffer,0,buffer.Length);
25
stream.Close();
26![](/Images/OutliningIndicators/InBlock.gif)
27
//声明并实例化WIN32.CRYPT_DATA_BLOB 将读取到的字节数组拷贝到它的pbData属性中。将字节数组长度赋给cbData属性
28
WIN32.CRYPT_DATA_BLOB cryptdata = new WIN32.CRYPT_DATA_BLOB();
29
cryptdata.cbData = buffer.Length;
30
cryptdata.pbData = Marshal.AllocHGlobal(cryptdata.cbData);
31
Marshal.Copy(buffer,0,cryptdata.pbData,buffer.Length);
32
IntPtr hMemStore = WIN32.PFXImportCertStore(ref cryptdata,"1234",WIN32.CRYPT_USER_KEYSET);
33
Marshal.FreeHGlobal(cryptdata.pbData);
34![](/Images/OutliningIndicators/InBlock.gif)
35
uint provinfosize = 0;
36
WIN32.CRYPT_KEY_PROV_INFO certinfo = new WIN32.CRYPT_KEY_PROV_INFO();
37![](/Images/OutliningIndicators/InBlock.gif)
38
System.Collections.ArrayList certs = new System.Collections.ArrayList();
39![](/Images/OutliningIndicators/InBlock.gif)
40
IntPtr certHandle = IntPtr.Zero;
41
while((certHandle = WIN32.CertEnumCertificatesInStore(hMemStore,certHandle)) != IntPtr.Zero) {
42![](/Images/OutliningIndicators/InBlock.gif)
43
if(WIN32.CertGetCertificateContextProperty(certHandle,WIN32.CERT_KEY_PROV_INFO_PROP_ID,IntPtr.Zero,ref provinfosize)){
44![](/Images/OutliningIndicators/InBlock.gif)
45
IntPtr info = Marshal.AllocHGlobal((int)provinfosize);
46![](/Images/OutliningIndicators/InBlock.gif)
47
if(WIN32.CertGetCertificateContextProperty(certHandle,WIN32.CERT_KEY_PROV_INFO_PROP_ID,info,ref provinfosize)) {
48
certinfo = (WIN32.CRYPT_KEY_PROV_INFO)Marshal.PtrToStructure(info,typeof(WIN32.CRYPT_KEY_PROV_INFO));
49![](/Images/OutliningIndicators/InBlock.gif)
50
certs.Add(new X509Certificate(certHandle));
51
}
52
Marshal.FreeHGlobal(info);
53![](/Images/OutliningIndicators/InBlock.gif)
54
}
55
}
56![](/Images/OutliningIndicators/InBlock.gif)
57
Marshal.FreeHGlobal(hMemStore);
58![](/Images/OutliningIndicators/InBlock.gif)
59
IntPtr hCryptProv = IntPtr.Zero;
60
if(!WIN32.CryptAcquireContext(ref hCryptProv,certinfo.ContainerName,certinfo.ProvName,certinfo.ProvType,WIN32.CRYPT_DELETEKEYSET))
61
throw new Exception("释放内存错误");
62
return (X509Certificate[])certs.ToArray(typeof(X509Certificate));
63
64
}
65
}
66
}
67![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/None.gif)
5
![](/Images/OutliningIndicators/None.gif)
6
![](/Images/OutliningIndicators/None.gif)
7
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
8
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
9
![](/Images/OutliningIndicators/InBlock.gif)
10
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
11
![](/Images/OutliningIndicators/InBlock.gif)
12
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
13
![](/Images/OutliningIndicators/InBlock.gif)
14
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
15
![](/Images/OutliningIndicators/InBlock.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/InBlock.gif)
18
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
19
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/InBlock.gif)
24
![](/Images/OutliningIndicators/InBlock.gif)
25
![](/Images/OutliningIndicators/InBlock.gif)
26
![](/Images/OutliningIndicators/InBlock.gif)
27
![](/Images/OutliningIndicators/InBlock.gif)
28
![](/Images/OutliningIndicators/InBlock.gif)
29
![](/Images/OutliningIndicators/InBlock.gif)
30
![](/Images/OutliningIndicators/InBlock.gif)
31
![](/Images/OutliningIndicators/InBlock.gif)
32
![](/Images/OutliningIndicators/InBlock.gif)
33
![](/Images/OutliningIndicators/InBlock.gif)
34
![](/Images/OutliningIndicators/InBlock.gif)
35
![](/Images/OutliningIndicators/InBlock.gif)
36
![](/Images/OutliningIndicators/InBlock.gif)
37
![](/Images/OutliningIndicators/InBlock.gif)
38
![](/Images/OutliningIndicators/InBlock.gif)
39
![](/Images/OutliningIndicators/InBlock.gif)
40
![](/Images/OutliningIndicators/InBlock.gif)
41
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
42
![](/Images/OutliningIndicators/InBlock.gif)
43
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
44
![](/Images/OutliningIndicators/InBlock.gif)
45
![](/Images/OutliningIndicators/InBlock.gif)
46
![](/Images/OutliningIndicators/InBlock.gif)
47
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
48
![](/Images/OutliningIndicators/InBlock.gif)
49
![](/Images/OutliningIndicators/InBlock.gif)
50
![](/Images/OutliningIndicators/InBlock.gif)
51
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
52
![](/Images/OutliningIndicators/InBlock.gif)
53
![](/Images/OutliningIndicators/InBlock.gif)
54
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
55
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
56
![](/Images/OutliningIndicators/InBlock.gif)
57
![](/Images/OutliningIndicators/InBlock.gif)
58
![](/Images/OutliningIndicators/InBlock.gif)
59
![](/Images/OutliningIndicators/InBlock.gif)
60
![](/Images/OutliningIndicators/InBlock.gif)
61
![](/Images/OutliningIndicators/InBlock.gif)
62
![](/Images/OutliningIndicators/InBlock.gif)
63
![](/Images/OutliningIndicators/InBlock.gif)
64
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
65
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
66
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
67
![](/Images/OutliningIndicators/None.gif)