RSA数字证书管理分为以下几个部分:
1:在存储区内创建数字证书;
2:导出数字证书私钥;
3:导出数字证书公钥;
4:导入数字证书;
5:读取数字证书。
1:在.net开发环境中,在证书存储区内创建数字证书
数字证书生成,需要指定证书主题,以及本机makecert.exe程序路径,因为证书制作实际上还是用makecert.exe来生成的。生成数字证书代码 如下:
1 /// <summary> 2 /// 根据指定的证书名和makecert全路径生成证书(包含公钥和私钥,并保存在MY存储区) 3 /// </summary> 4 /// <param name="subjectName"></param> 5 /// <param name="makecertPath"></param> 6 /// <returns></returns> 7 public static bool CreateCertWithPrivateKey(string subjectName, string makecertPath) 8 { 9 subjectName = "CN=" + subjectName; 10 string param = " -pe -ss my -n "" + subjectName + "" "; 11 try 12 { 13 Process p = Process.Start(makecertPath, param); 14 p.WaitForExit(); 15 p.Close(); 16 } 17 catch (Exception e) 18 { 19 return false; 20 } 21 return true; 22 }
2:导出数字证书公钥
导出数字证书的公钥(cer)需要指定需要导出的证书主题,并指定路径,从系统证书存储区导出cer公钥文件,代码如下:
1 /// <summary> 2 /// 从WINDOWS证书存储区的个人MY区找到主题为subjectName的证书,并导出为CER文件 3 /// </summary> 4 /// <param name="subjectName"></param> 5 /// <param name="cerFileName"></param> 6 /// <returns></returns> 7 public static bool ExportToCerFile(string subjectName, string cerFileName) 8 { 9 subjectName = "CN=" + subjectName; 10 var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); 11 store.Open(OpenFlags.ReadWrite); 12 var storecollection = store.Certificates; 13 foreach (var x509 in storecollection) 14 { 15 if (x509.Subject == subjectName) 16 { 17 Debug.Print(string.Format("certificate name: {0}", x509.Subject)); 18 //byte[] pfxByte = x509.Export(X509ContentType.Pfx, password); 19 byte[] cerByte = x509.Export(X509ContentType.Cert); 20 using (var fileStream = new FileStream(cerFileName, FileMode.Create)) 21 { 22 // Write the data to the file, byte by byte. 23 for (var i = 0; i < cerByte.Length; i++) 24 fileStream.WriteByte(cerByte[i]); 25 // Set the stream position to the beginning of the file. 26 fileStream.Seek(0, SeekOrigin.Begin); 27 // Read and verify the data. 28 for (var i = 0; i < fileStream.Length; i++) 29 { 30 if (cerByte[i] != fileStream.ReadByte()) 31 { 32 fileStream.Close(); 33 return false; 34 } 35 } 36 fileStream.Close(); 37 } 38 } 39 } 40 store.Close(); 41 store = null; 42 storecollection = null; 43 return true; 44 }
3:导出数字证书私钥
导出数字证书的私钥(pfx)需要指定需要导出的证书主题,私钥证书密码,以及保存路径,从系统证书存储区导出pfx私钥文件,代码如下:
1 /// <summary> 2 /// 从WINDOWS证书存储区的个人MY区找到主题为subjectName的证书, 3 /// 并导出为pfx文件,同时为其指定一个密码 4 /// 并将证书从个人区删除(如果isDelFromstore为true) 5 /// </summary> 6 /// <param name="subjectName">证书主题,不包含CN=</param> 7 /// <param name="pfxFileName">pfx文件名</param> 8 /// <param name="password">pfx文件密码</param> 9 /// <param name="isDelFromStore">是否从存储区删除</param> 10 /// <returns></returns> 11 public static bool ExportToPfxFile(string subjectName, string pfxFileName, 12 string password, bool isDelFromStore) 13 { 14 subjectName = "CN=" + subjectName; 15 var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); 16 store.Open(OpenFlags.ReadWrite); 17 var storecollection = store.Certificates; 18 foreach (var x509 in storecollection) 19 { 20 if (x509.Subject == subjectName) 21 { 22 Debug.Print(string.Format("certificate name: {0}", x509.Subject)); 23 24 byte[] pfxByte = x509.Export(X509ContentType.Pfx, password); 25 using (var fileStream = new FileStream(pfxFileName, FileMode.Create)) 26 { 27 // Write the data to the file, byte by byte. 28 for (int i = 0; i < pfxByte.Length; i++) 29 fileStream.WriteByte(pfxByte[i]); 30 // Set the stream position to the beginning of the file. 31 fileStream.Seek(0, SeekOrigin.Begin); 32 // Read and verify the data. 33 for (var i = 0; i < fileStream.Length; i++) 34 { 35 if (pfxByte[i] != fileStream.ReadByte()) 36 { 37 fileStream.Close(); 38 return false; 39 } 40 } 41 fileStream.Close(); 42 } 43 if (isDelFromStore == true) 44 store.Remove(x509); 45 } 46 } 47 store.Close(); 48 store = null; 49 storecollection = null; 50 return true; 51 }
4:导入数字证书
在获取了数字证书的公钥与私钥文件之后,
服务器端导入pfx数字证书(私钥),在客户端导入cer数字证书(公钥)。具体导入注意事项如下:
1:数字证书(cer,pfx)导入的存储位置选择“本地计算机”;
2:私钥证书(pfx)导入需要输入数字证书生成密码,并且勾选”标志此密钥为可导出的密钥…“复选框;
3:指定证书导入位置,浏览选择项:“可信任人”选项;
服务器端及客户端均按照上述流程导入即可。
5:读取数字证书
读取私钥证书:
1 /// <summary> 2 /// 根据私钥证书得到证书实体,得到实体后可以根据其公钥和私钥进行加解密 3 /// 加解密函数使用DEncrypt的RSACryption类 4 /// </summary> 5 /// <param name="pfxFileName"></param> 6 /// <param name="password"></param> 7 /// <returns></returns> 8 public static X509Certificate2 GetCertificateFromPfxFile(string pfxFileName, 9 string password) 10 { 11 try 12 { 13 return new X509Certificate2(pfxFileName, password, X509KeyStorageFlags.Exportable); 14 } 15 catch (Exception e) 16 { 17 return null; 18 } 19 }
读取公钥证书:
1 /// <summary> 2 /// 根据公钥证书,返回证书实体 3 /// </summary> 4 /// <param name="cerPath"></param> 5 public static X509Certificate2 GetCertFromCerFile(string cerPath) 6 { 7 try 8 { 9 return new X509Certificate2(cerPath); 10 } 11 catch (Exception e) 12 { 13 return null; 14 } 15 }