1. 程式人生 > >詳解關於Pfx與cer之間的關系

詳解關於Pfx與cer之間的關系

pfx phy etc 自簽名 cati 證書 foreach byte[] []

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之間的關系