詳解關於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證書采用了技術含量比較高的加密技術。
詳解關於Pfx與cer之間的關系