详解关于Pfx与cer之间的关系

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证书采用了技术含量比较高的加密技术。

猜你喜欢

转载自blog.51cto.com/13931430/2368780
今日推荐