必威体育Betway必威体育官网
当前位置:首页 > IT技术

cer, pfx 创建,并且读取公钥/密钥,加解密 (C#程序实现)

时间:2019-07-06 13:42:42来源:IT技术作者:seo实验室小编阅读:89次「手机版」
 

cer

HTTP://blog.csdn.net/zj510/article/details/39964533

PKI技术(public key infrastructure)里面,cer文件和pfx文件是很常见的。通常cer文件里面保存着公钥以及用户的一些信息,pfx里面则含有私钥和公钥。

用makecert.exe可以创建公钥证书和私钥证书,具体看

http://msdn.microsoft.com/zh-cn/library/bfsktky3(v=vs.110).aspx

http://blog.csdn.net/hacode/article/details/4240238

这里使用程序的方法来创建。参考了http://www.cnblogs.com/luminji/archive/2010/10/28/1863179.HTML

下面的代码封装了一个类,可以在store里面创建一个认证,并且导出到cer,pfx,然后从store,cer,pfx读取信息

[csharp]view plaincopy

  1. publicsealedclassDataCertificate
  2. {
  3. #region生成证书
  4. ///<summary>
  5. ///根据指定的证书名和makecert全路径生成证书(包含公钥和私钥,并保存在MY存储区)
  6. ///</summary>
  7. ///<paramname="subjectName"></param>
  8. ///<paramname="makecertPath"></param>
  9. ///<returns></returns>
  10. publicstaticboolCreateCertwithPrivateKey(stringsubjectName,stringmakecertPath)
  11. {
  12. subjectName="CN="+subjectName;
  13. stringparam="-pe-ssmy-n\""+subjectName+"\"";
  14. try
  15. {
  16. Processp=Process.Start(makecertPath,param);
  17. p.waitforExit();
  18. p.Close();
  19. }
  20. catch(Exceptione)
  21. {
  22. returnfalse;
  23. }
  24. returntrue;
  25. }
  26. #endregion
  27. #region文件导入导出
  28. ///<summary>
  29. ///从windows证书存储区的个人MY区找到主题为subjectName的证书,
  30. ///并导出为pfx文件,同时为其指定一个密码
  31. ///并将证书从个人区删除(如果isDelFromstor为true)
  32. ///</summary>
  33. ///<paramname="subjectName">证书主题,不包含CN=</param>
  34. ///<paramname="pfxFileName">pfx文件名</param>
  35. ///<paramname="password">pfx文件密码</param>
  36. ///<paramname="isDelFromStore">是否从存储区删除</param>
  37. ///<returns></returns>
  38. publicstaticboolExportToPfxFile(stringsubjectName,stringpfxFileName,
  39. stringpassword,boolisDelFromStore)
  40. {
  41. subjectName="CN="+subjectName;
  42. X509Storestore=newX509Store(StoreName.My,StoreLocation.CurrentUser);
  43. store.Open(OpenFlags.ReadWrite);
  44. X509Certificate2Collectionstorecollection=(X509Certificate2Collection)store.Certificates;
  45. foreach(X509Certificate2x509instorecollection)
  46. {
  47. if(x509.Subject==subjectName)
  48. {
  49. Debug.print(string.format("certificatename:{0}",x509.Subject));
  50. byte[]pfxByte=x509.Export(X509contentType.Pfx,password);
  51. using(filestreamfileStream=newFileStream(pfxFileName,FileMode.Create))
  52. {
  53. //Writethedatatothefile,bytebybyte.
  54. for(inti=0;i<pfxByte.Length;i++)
  55. fileStream.WriteByte(pfxByte[i]);
  56. //Setthestreampositiontothebeginningofthefile.
  57. fileStream.Seek(0,SeekOrigin.Begin);
  58. //Readandverifythedata.
  59. for(inti=0;i<fileStream.Length;i++)
  60. {
  61. if(pfxByte[i]!=fileStream.ReadByte())
  62. {
  63. fileStream.Close();
  64. returnfalse;
  65. }
  66. }
  67. fileStream.Close();
  68. }
  69. if(isDelFromStore==true)
  70. store.Remove(x509);
  71. }
  72. }
  73. store.Close();
  74. store=null;
  75. storecollection=null;
  76. returntrue;
  77. }
  78. ///<summary>
  79. ///从WINDOWS证书存储区的个人MY区找到主题为subjectName的证书,
  80. ///并导出为CER文件(即,只含公钥的)
  81. ///</summary>
  82. ///<paramname="subjectName"></param>
  83. ///<paramname="cerFileName"></param>
  84. ///<returns></returns>
  85. publicstaticboolExportToCerFile(stringsubjectName,stringcerFileName)
  86. {
  87. subjectName="CN="+subjectName;
  88. X509Storestore=newX509Store(StoreName.My,StoreLocation.CurrentUser);
  89. store.Open(OpenFlags.ReadWrite);
  90. X509Certificate2Collectionstorecollection=(X509Certificate2Collection)store.Certificates;
  91. foreach(X509Certificate2x509instorecollection)
  92. {
  93. if(x509.Subject==subjectName)
  94. {
  95. Debug.Print(string.Format("certificatename:{0}",x509.Subject));
  96. //byte[]pfxByte=x509.Export(X509ContentType.Pfx,password);
  97. byte[]cerByte=x509.Export(X509ContentType.Cert);
  98. using(FileStreamfileStream=newFileStream(cerFileName,FileMode.Create))
  99. {
  100. //Writethedatatothefile,bytebybyte.
  101. for(inti=0;i<cerByte.Length;i++)
  102. fileStream.WriteByte(cerByte[i]);
  103. //Setthestreampositiontothebeginningofthefile.
  104. fileStream.Seek(0,SeekOrigin.Begin);
  105. //Readandverifythedata.
  106. for(inti=0;i<fileStream.Length;i++)
  107. {
  108. if(cerByte[i]!=fileStream.ReadByte())
  109. {
  110. fileStream.Close();
  111. returnfalse;
  112. }
  113. }
  114. fileStream.Close();
  115. }
  116. }
  117. }
  118. store.Close();
  119. store=null;
  120. storecollection=null;
  121. returntrue;
  122. }
  123. #endregion
  124. #region从证书中获取信息
  125. ///<summary>
  126. ///根据私钥证书得到证书实体,得到实体后可以根据其公钥和私钥进行加解密
  127. ///加解密函数使用DEncrypt的RSACryption类
  128. ///</summary>
  129. ///<paramname="pfxFileName"></param>
  130. ///<paramname="password"></param>
  131. ///<returns></returns>
  132. publicstaticX509Certificate2GetCertificateFromPfxFile(stringpfxFileName,
  133. stringpassword)
  134. {
  135. try
  136. {
  137. returnnewX509Certificate2(pfxFileName,password,X509KeyStorageFlags.Exportable);
  138. }
  139. catch(Exceptione)
  140. {
  141. returnnull;
  142. }
  143. }
  144. ///<summary>
  145. ///到存储区获取证书
  146. ///</summary>
  147. ///<paramname="subjectName"></param>
  148. ///<returns></returns>
  149. publicstaticX509Certificate2GetCertificateFromStore(stringsubjectName)
  150. {
  151. subjectName="CN="+subjectName;
  152. X509Storestore=newX509Store(StoreName.My,StoreLocation.CurrentUser);
  153. store.Open(OpenFlags.ReadWrite);
  154. X509Certificate2Collectionstorecollection=(X509Certificate2Collection)store.Certificates;
  155. foreach(X509Certificate2x509instorecollection)
  156. {
  157. if(x509.Subject==subjectName)
  158. {
  159. returnx509;
  160. }
  161. }
  162. store.Close();
  163. store=null;
  164. storecollection=null;
  165. returnnull;
  166. }
  167. ///<summary>
  168. ///根据公钥证书,返回证书实体
  169. ///</summary>
  170. ///<paramname="cerPath"></param>
  171. publicstaticX509Certificate2GetCertFromCerFile(stringcerPath)
  172. {
  173. try
  174. {
  175. returnnewX509Certificate2(cerPath);
  176. }
  177. catch(Exceptione)
  178. {
  179. returnnull;
  180. }
  181. }
  182. #endregion
  183. }

两个RSA加解密辅助函数:

[csharp]view plaincopy

  1. staticstringRSADecrypt(stringxmlPrivateKey,stringm_strDecryptString)
  2. {
  3. RSACryptoServiceProviderprovider=newRSACryptoServiceProvider();
  4. provider.FromXmlString(xmlPrivateKey);
  5. byte[]rgb=Convert.Frombase64String(m_strDecryptString);
  6. byte[]bytes=provider.Decrypt(rgb,false);
  7. returnnewunicodeEncoding().GetString(bytes);
  8. }
  9. ///<summary>
  10. ///RSA加密
  11. ///</summary>
  12. ///<paramname="xmlPublicKey"></param>
  13. ///<paramname="m_strEncryptString"></param>
  14. ///<returns></returns>
  15. staticstringRSAEncrypt(stringxmlPublicKey,stringm_strEncryptString)
  16. {
  17. RSACryptoServiceProviderprovider=newRSACryptoServiceProvider();
  18. provider.FromXmlString(xmlPublicKey);
  19. byte[]bytes=newUnicodeEncoding().GetBytes(m_strEncryptString);
  20. returnConvert.ToBase64String(provider.Encrypt(bytes,false));
  21. }

使用例子,下面的代码做了几个事情

1. 在个人store里面创建了一个认证, 从认证里面读取信息得到一个X509Certificate2的对象,这个对象内部包含公钥和私钥,然后做了次rsa加解密测试。

2. 从store里面导出一个cer文件,因为cer文件并没有私钥,只有公钥。测试代码就是用公钥加密然后用前面得到的私钥解密。

3. 导出一个pfx文件,pfx包括公钥和私钥,可以自己加解密。

这是个很简单的例子,但是对于理解cer文件和pfx文件已经公钥私钥应该有帮助。

[csharp]view plaincopy

  1. //在personal(个人)里面创建一个foo的证书
  2. DataCertificate.CreateCertWithPrivateKey("foo","C:\\ProgramFiles(x86)\\WindowsKits\\8.1\\bin\\x64\\makecert.exe");
  3. //获取证书
  4. X509Certificate2c1=DataCertificate.GetCertificateFromStore("foo");
  5. stringkeyPublic=c1.PublicKey.Key.ToXmlString(false);//公钥
  6. stringkeyPrivate=c1.PrivateKey.ToXmlString(true);//私钥
  7. stringcypher=RSAEncrypt(keyPublic,"程序员");//加密
  8. stringplain=RSADecrypt(keyPrivate,cypher);//解密
  9. Debug.Assert(plain=="程序员");
  10. //生成一个cert文件
  11. DataCertificate.ExportToCerFile("foo","d:\\mycert\\foo.cer");
  12. X509Certificate2c2=DataCertificate.GetCertFromCerFile("d:\\mycert\\foo.cer");
  13. stringkeyPublic2=c2.PublicKey.Key.ToXmlString(false);
  14. boolb=keyPublic2==keyPublic;
  15. stringcypher2=RSAEncrypt(keyPublic2,"程序员2");//加密
  16. stringplain2=RSADecrypt(keyPrivate,cypher2);//解密,cer里面并没有私钥,所以这里使用前面得到的私钥来解密
  17. Debug.Assert(plain2=="程序员2");
  18. //生成一个pfx,并且从store里面删除
  19. DataCertificate.ExportToPfxFile("foo","d:\\mycert\\foo.pfx","111",true);
  20. X509Certificate2c3=DataCertificate.GetCertificateFromPfxFile("d:\\mycert\\foo.pfx","111");
  21. stringkeyPublic3=c3.PublicKey.Key.ToXmlString(false);//公钥
  22. stringkeyPrivate3=c3.PrivateKey.ToXmlString(true);//私钥
  23. stringcypher3=RSAEncrypt(keyPublic3,"程序员3");//加密
  24. stringplain3=RSADecrypt(keyPrivate3,cypher3);//解密
  25. Debug.Assert(plain3=="程序员3");

附:完整代码

[csharp]view plaincopy

  1. usingSystem;
  2. usingSystem.Collections.Generic;
  3. usingSystem.Diagnostics;
  4. usingSystem.IO;
  5. usingSystem.Linq;
  6. usingSystem.Security.Cryptography;
  7. usingSystem.Security.Cryptography.X509Certificates;
  8. usingSystem.Text;
  9. namespaceconsoleAPPlication1
  10. {
  11. publicsealedclassDataCertificate
  12. {
  13. #region生成证书
  14. ///<summary>
  15. ///根据指定的证书名和makecert全路径生成证书(包含公钥和私钥,并保存在MY存储区)
  16. ///</summary>
  17. ///<paramname="subjectName"></param>
  18. ///<paramname="makecertPath"></param>
  19. ///<returns></returns>
  20. publicstaticboolCreateCertWithPrivateKey(stringsubjectName,stringmakecertPath)
  21. {
  22. subjectName="CN="+subjectName;
  23. stringparam="-pe-ssmy-n\""+subjectName+"\"";
  24. try
  25. {
  26. Processp=Process.Start(makecertPath,param);
  27. p.WaitForExit();
  28. p.Close();
  29. }
  30. catch(Exceptione)
  31. {
  32. returnfalse;
  33. }
  34. returntrue;
  35. }
  36. #endregion
  37. #region文件导入导出
  38. ///<summary>
  39. ///从WINDOWS证书存储区的个人MY区找到主题为subjectName的证书,
  40. ///并导出为pfx文件,同时为其指定一个密码
  41. ///并将证书从个人区删除(如果isDelFromstor为true)
  42. ///</summary>
  43. ///<paramname="subjectName">证书主题,不包含CN=</param>
  44. ///<paramname="pfxFileName">pfx文件名</param>
  45. ///<paramname="password">pfx文件密码</param>
  46. ///<paramname="isDelFromStore">是否从存储区删除</param>
  47. ///<returns></returns>
  48. publicstaticboolExportToPfxFile(stringsubjectName,stringpfxFileName,
  49. stringpassword,boolisDelFromStore)
  50. {
  51. subjectName="CN="+subjectName;
  52. X509Storestore=newX509Store(StoreName.My,StoreLocation.CurrentUser);
  53. store.Open(OpenFlags.ReadWrite);
  54. X509Certificate2Collectionstorecollection=(X509Certificate2Collection)store.Certificates;
  55. foreach(X509Certificate2x509instorecollection)
  56. {
  57. if(x509.Subject==subjectName)
  58. {
  59. Debug.Print(string.Format("certificatename:{0}",x509.Subject));
  60. byte[]pfxByte=x509.Export(X509ContentType.Pfx,password);
  61. using(FileStreamfileStream=newFileStream(pfxFileName,FileMode.Create))
  62. {
  63. //Writethedatatothefile,bytebybyte.
  64. for(inti=0;i<pfxByte.Length;i++)
  65. fileStream.WriteByte(pfxByte[i]);
  66. //Setthestreampositiontothebeginningofthefile.
  67. fileStream.Seek(0,SeekOrigin.Begin);
  68. //Readandverifythedata.
  69. for(inti=0;i<fileStream.Length;i++)
  70. {
  71. if(pfxByte[i]!=fileStream.ReadByte())
  72. {
  73. fileStream.Close();
  74. returnfalse;
  75. }
  76. }
  77. fileStream.Close();
  78. }
  79. if(isDelFromStore==true)
  80. store.Remove(x509);
  81. }
  82. }
  83. store.Close();
  84. store=null;
  85. storecollection=null;
  86. returntrue;
  87. }
  88. ///<summary>
  89. ///从WINDOWS证书存储区的个人MY区找到主题为subjectName的证书,
  90. ///并导出为CER文件(即,只含公钥的)
  91. ///</summary>
  92. ///<paramname="subjectName"></param>
  93. ///<paramname="cerFileName"></param>
  94. ///<returns></returns>
  95. publicstaticboolExportToCerFile(stringsubjectName,stringcerFileName)
  96. {
  97. subjectName="CN="+subjectName;
  98. X509Storestore=newX509Store(StoreName.My,StoreLocation.CurrentUser);
  99. store.Open(OpenFlags.ReadWrite);
  100. X509Certificate2Collectionstorecollection=(X509Certificate2Collection)store.Certificates;
  101. foreach(X509Certificate2x509instorecollection)
  102. {
  103. if(x509.Subject==subjectName)
  104. {
  105. Debug.Print(string.Format("certificatename:{0}",x509.Subject));
  106. //byte[]pfxByte=x509.Export(X509ContentType.Pfx,password);
  107. byte[]cerByte=x509.Export(X509ContentType.Cert);
  108. using(FileStreamfileStream=newFileStream(cerFileName,FileMode.Create))
  109. {
  110. //Writethedatatothefile,bytebybyte.
  111. for(inti=0;i<cerByte.Length;i++)
  112. fileStream.WriteByte(cerByte[i]);
  113. //Setthestreampositiontothebeginningofthefile.
  114. fileStream.Seek(0,SeekOrigin.Begin);
  115. //Readandverifythedata.
  116. for(inti=0;i<fileStream.Length;i++)
  117. {
  118. if(cerByte[i]!=fileStream.ReadByte())
  119. {
  120. fileStream.Close();
  121. returnfalse;
  122. }
  123. }
  124. fileStream.Close();
  125. }
  126. }
  127. }
  128. store.Close();
  129. store=null;
  130. storecollection=null;
  131. returntrue;
  132. }
  133. #endregion
  134. #region从证书中获取信息
  135. ///<summary>
  136. ///根据私钥证书得到证书实体,得到实体后可以根据其公钥和私钥进行加解密
  137. ///加解密函数使用DEncrypt的RSACryption类
  138. ///</summary>
  139. ///<paramname="pfxFileName"></param>
  140. ///<paramname="password"></param>
  141. ///<returns></returns>
  142. publicstaticX509Certificate2GetCertificateFromPfxFile(stringpfxFileName,
  143. stringpassword)
  144. {
  145. try
  146. {
  147. returnnewX509Certificate2(pfxFileName,password,X509KeyStorageFlags.Exportable);
  148. }
  149. catch(Exceptione)
  150. {
  151. returnnull;
  152. }
  153. }
  154. ///<summary>
  155. ///到存储区获取证书
  156. ///</summary>
  157. ///<paramname="subjectName"></param>
  158. ///<returns></returns>
  159. publicstaticX509Certificate2GetCertificateFromStore(stringsubjectName)
  160. {
  161. subjectName="CN="+subjectName;
  162. X509Storestore=newX509Store(StoreName.My,StoreLocation.CurrentUser);
  163. store.Open(OpenFlags.ReadWrite);
  164. X509Certificate2Collectionstorecollection=(X509Certificate2Collection)store.Certificates;
  165. foreach(X509Certificate2x509instorecollection)
  166. {
  167. if(x509.Subject==subjectName)
  168. {
  169. returnx509;
  170. }
  171. }
  172. store.Close();
  173. store=null;
  174. storecollection=null;
  175. returnnull;
  176. }
  177. ///<summary>
  178. ///根据公钥证书,返回证书实体
  179. ///</summary>
  180. ///<paramname="cerPath"></param>
  181. publicstaticX509Certificate2GetCertFromCerFile(stringcerPath)
  182. {
  183. try
  184. {
  185. returnnewX509Certificate2(cerPath);
  186. }
  187. catch(Exceptione)
  188. {
  189. returnnull;
  190. }
  191. }
  192. #endregion
  193. }
  194. classProgram
  195. {
  196. staticstringRSADecrypt(stringxmlPrivateKey,stringm_strDecryptString)
  197. {
  198. RSACryptoServiceProviderprovider=newRSACryptoServiceProvider();
  199. provider.FromXmlString(xmlPrivateKey);
  200. byte[]rgb=Convert.FromBase64String(m_strDecryptString);
  201. byte[]bytes=provider.Decrypt(rgb,false);
  202. returnnewUnicodeEncoding().GetString(bytes);
  203. }
  204. ///<summary>
  205. ///RSA加密
  206. ///</summary>
  207. ///<paramname="xmlPublicKey"></param>
  208. ///<paramname="m_strEncryptString"></param>
  209. ///<returns></returns>
  210. staticstringRSAEncrypt(stringxmlPublicKey,stringm_strEncryptString)
  211. {
  212. RSACryptoServiceProviderprovider=newRSACryptoServiceProvider();
  213. provider.FromXmlString(xmlPublicKey);
  214. byte[]bytes=newUnicodeEncoding().GetBytes(m_strEncryptString);
  215. returnConvert.ToBase64String(provider.Encrypt(bytes,false));
  216. }
  217. staticvoidMain(string[]args)
  218. {
  219. //在personal(个人)里面创建一个foo的证书
  220. DataCertificate.CreateCertWithPrivateKey("foo","C:\\ProgramFiles(x86)\\WindowsKits\\8.1\\bin\\x64\\makecert.exe");
  221. //获取证书
  222. X509Certificate2c1=DataCertificate.GetCertificateFromStore("foo");
  223. stringkeyPublic=c1.PublicKey.Key.ToXmlString(false);//公钥
  224. stringkeyPrivate=c1.PrivateKey.ToXmlString(true);//私钥
  225. stringcypher=RSAEncrypt(keyPublic,"程序员");//加密
  226. stringplain=RSADecrypt(keyPrivate,cypher);//解密
  227. Debug.Assert(plain=="程序员");
  228. //生成一个cert文件
  229. DataCertificate.ExportToCerFile("foo","d:\\mycert\\foo.cer");
  230. X509Certificate2c2=DataCertificate.GetCertFromCerFile("d:\\mycert\\foo.cer");
  231. stringkeyPublic2=c2.PublicKey.Key.ToXmlString(false);
  232. boolb=keyPublic2==keyPublic;
  233. stringcypher2=RSAEncrypt(keyPublic2,"程序员2");//加密
  234. stringplain2=RSADecrypt(keyPrivate,cypher2);//解密,cer里面并没有私钥,所以这里使用前面得到的私钥来解密
  235. Debug.Assert(plain2=="程序员2");
  236. //生成一个pfx,并且从store里面删除
  237. DataCertificate.ExportToPfxFile("foo","d:\\mycert\\foo.pfx","111",true);
  238. X509Certificate2c3=DataCertificate.GetCertificateFromPfxFile("d:\\mycert\\foo.pfx","111");
  239. stringkeyPublic3=c3.PublicKey.Key.ToXmlString(false);//公钥
  240. stringkeyPrivate3=c3.PrivateKey.ToXmlString(true);//私钥
  241. stringcypher3=RSAEncrypt(keyPublic3,"程序员3");//加密
  242. stringplain3=RSADecrypt(keyPrivate3,cypher3);//解密
  243. Debug.Assert(plain3=="程序员3");
  244. }
  245. }
  246. }

相关阅读

tcptraceroute与traceroute

1 traceroute 功能说明:显示数据包到主机间的路径。它默认发送的数据包大小是40字节。 通过traceroute我们可以知道信息从你的计

Packet Tracer 思科模拟器入门教程 之一 初识Packet T

Packet Tracer介绍 Packet Tracer是Cisco公司针对CCNA认证开发的一个用来设计、配置和故障排除网络的模拟软件。 Packer Tracer

宏基/Acer E1-471Gb如何拆机清洁?

本本从2012-12-25购买到现在快3年了,期间把内存增加到8G,硬盘升级为1T的,一直任劳任怨得为我工作着,最近感觉散热不是很好,决定拆

Gooogle发布生成https加密证书工具mkcert

谷歌日前正加快速度完成一项关于mkcert的开源项目,项目本身允许开发者在本地部署https测试环境,而mkcert是一个能够让网站通过自动

宏碁ACER4752G怎么拆机更换内存条?

笔记本电脑的内存和电脑的操作体验有很大的关系,往往换更大的内存电脑会更流畅,可以开启的任务也更多,这篇和大家分享如何给宏碁acer

分享到:

栏目导航

推荐阅读

热门阅读