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