Pfx与cer均为证书的文件格式,他们之间区别为
1.带有私钥的证书
由Public Key Cryptography Standards #12,PKCS#12标准定义,包含了公钥和私钥的二进制格式的证书形式,以pfx作为证书文件后缀名。
2.二进制编码的证书
证书中没有私钥,DER 编码二进制格式的证书文件,以cer作为证书文件后缀名。
3.Base64编码的证书
证书中没有私钥,BASE64 编码格式的证书文件,也是以cer作为证书文件后缀名。
由定义可以看出,只有pfx格式的数字证书是包含有私钥的,cer格式的数字证书里面只有公钥没有私钥。
在pfx证书的导入过程中有一项是“标志此密钥是可导出的。这将您在稍候备份或传输密钥”。一般是不选中的,如果选中,别人就有机会备份你的密钥了。如果是不选中,其实密钥也导入了,只是不能再次被导出。这就保证了密钥的安全。
如果导入过程中没有选中这一项,做证书备份时“导出私钥”这一项是灰色的,不能选。只能导出cer格式的公钥。如果导入时选中该项,则在导出时“导出私钥”这一项就是可选的。
如果要导出私钥(pfx),是需要输入密码的,这个密码就是对私钥再次加密,这样就保证了私钥的安全,别人即使拿到了你的证书备份(pfx),不知道加密私钥的密码,也是无法导入证书的。相反,如果只是导入导出cer格式的证书,是不会提示你输入密码的。因为公钥一般来说是对外公开的,不用加密。
下面介绍关于自签名证书导出pfx和cer证书
完整代码:
1publicsealedclassDataCertificate
2{
3#region生成证书
4///<summary>
5///根据指定的证书名和makecert全路径生成证书(包含公钥和私钥,并保存在MY存储区)
6///</summary>
7///<param name=”subjectName”></param>
8///<param name=”makecertPath”></param>
9///<returns></returns>
10publicstaticboolCreateCertWithPrivateKey(stringsubjectName, stringmakecertPath)
11{
12subjectName = “CN=”+ subjectName;
13stringparam = ” -pe -ss my -n \””+ subjectName + “\” “;
14try
15{
16Process p = Process.Start(makecertPath, param);
17p.WaitForExit();
18p.Close();
19}
20catch(Exception e)
21{
22returnfalse;
23}
24returntrue;
25}
26#endregion
27
28#region文件导入导出
29///<summary>
30///从WINDOWS证书存储区的个人MY区找到主题为subjectName的证书,
31///并导出为pfx文件,同时为其指定一个密码
32///并将证书从个人区删除(如果isDelFromstor为true)
33///</summary>
34///<param name=”subjectName”>证书主题,不包含CN=</param>
35///<param name=”pfxFileName”>pfx文件名</param>
36///<param name=”password”>pfx文件密码</param>
37///<param name=”isDelFromStore”>是否从存储区删除</param>
38///<returns></returns>
39publicstaticboolExportToPfxFile(stringsubjectName, stringpfxFileName,
40stringpassword, boolisDelFromStore)
41{
42subjectName = “CN=”+ subjectName;
43X509Store store = newX509Store(StoreName.My, StoreLocation.CurrentUser);
44store.Open(OpenFlags.ReadWrite);
45X509Certificate2Collection storecollection = (X509Certificate2Collection)store.Certificates;
46foreach(X509Certificate2 x509 instorecollection)
47{
48if(x509.Subject == subjectName)
49{
50Debug.Print(string.Format(“certificate name: {0}”, x509.Subject));
51
52byte[] pfxByte = x509.Export(X509ContentType.Pfx, password);
53using(FileStream fileStream = newFileStream(pfxFileName, FileMode.Create))
54{
55// Write the data to the file, byte by byte.
56for(inti = 0; i < pfxByte.Length; i++)
57fileStream.WriteByte(pfxByte[i]);
58// Set the stream position to the beginning of the file.
59fileStream.Seek(0, SeekOrigin.Begin);
60// Read and verify the data.
61for(inti = 0; i < fileStream.Length; i++)
62{
63if(pfxByte[i] != fileStream.ReadByte())
64{
65fileStream.Close();66returnfalse;
67}
68}
69fileStream.Close();
70}
71if(isDelFromStore == true)
72store.Remove(x509);
73}
74}
75store.Close();
76returntrue;
77}
78///<summary>
79///从WINDOWS证书存储区的个人MY区找到主题为subjectName的证书,
80///并导出为CER文件(即,只含公钥的)
81///</summary>
82///<param name=”subjectName”></param>
83///<param name=”cerFileName”></param>
84///<returns></returns>
85publicstaticboolExportToCerFile(stringsubjectName, stringcerFileName)
86{
87subjectName = “CN=”+ subjectName;
88X509Store store = newX509Store(StoreName.My, StoreLocation.CurrentUser);
89store.Open(OpenFlags.ReadWrite);
90X509Certificate2Collection storecollection = (X509Certificate2Collection)store.Certificates;
91foreach(X509Certificate2 x509 instorecollection)
92{
93if(x509.Subject == subjectName)
94{
95Debug.Print(string.Format(“certificate name: {0}”, x509.Subject));
96//byte[] pfxByte = x509.Export(X509ContentType.Pfx, password);
97byte[] cerByte = x509.Export(X509ContentType.Cert);
98using(FileStream fileStream = newFileStream(cerFileName, FileMode.Create))
99{
100// Write the data to the file, byte by byte.
101for(inti = 0; i < cerByte.Length; i++)
102fileStream.WriteByte(cerByte[i]);
103// Set the stream position to the beginning of the file.
104fileStream.Seek(0, SeekOrigin.Begin);
105// Read and verify the data.
106for(inti = 0; i < fileStream.Length; i++)
107{
108if(cerByte[i] != fileStream.ReadByte())
109{
110fileStream.Close();
111returnfalse;
112}
113}
114fileStream.Close();115}
116}
117}
118store.Close();
119store = null;
120storecollection = null;
121returntrue;
122}
123#endregion
124
125#region从证书中获取信息
126///<summary>
127///根据私钥证书得到证书实体,得到实体后可以根据其公钥和私钥进行加解密
128///加解密函数使用DEncrypt的RSACryption类
129///</summary>
130///<param name=”pfxFileName”></param>
131///<param name=”password”></param>
132///<returns></returns>
133publicstaticX509Certificate2 GetCertificateFromPfxFile(stringpfxFileName,
134stringpassword)135{
136try
137{
138returnnewX509Certificate2(pfxFileName, password, X509KeyStorageFlags.Exportable);
139}
140catch(Exception e)
141
{142returnnull;
143}
144}
145///<summary>
146///到存储区获取证书
147///</summary>
148///<param name=”subjectName”></param>
149///<returns></returns>
150publicstaticX509Certificate2 GetCertificateFromStore(stringsubjectName)
151{
152subjectName = “CN=”+ subjectName;
153X509Store store = newX509Store(StoreName.My, StoreLocation.CurrentUser);
154store.Open(OpenFlags.ReadWrite);
155X509Certificate2Collection storecollection = (X509Certificate2Collection)store.Certificates;
156foreach(X509Certificate2 x509 instorecollection)
157{
158if(x509.Subject == subjectName)
159{
160returnx509;
161}
162}
163store.Close();
164store = null;
165storecollection = null;166returnnull;
167}
168///<summary>
169///根据公钥证书,返回证书实体
170///</summary>
171///<param name=”cerPath”></param>
172publicstaticX509Certificate2 GetCertFromCerFile(stringcerPath)
173{
174try
175{
176returnnewX509Certificate2(cerPath);177}
178catch(Exception e)179{
180returnnull;181}
182}
183#endregion184}
SSL证书采用了技术含量比较高的加密技术。日后GDCA()将会持续为大家推荐更多关于SSL证书的技术知识。让大家正确认识SSL证书,快速无误部署HTTPS安全协议。更多资讯,请关注GDCA。
猜你喜欢