zoukankan      html  css  js  c++  java
  • (转)C#创建数字证书并导出为pfx,并使用pfx进行非对称加解密

    我的项目当中,考虑到安全性,需要为每个客户端分发一个数字证书,同时使用数字证书中的公私钥来进行数据的加解密。为了完成这个安全模块,特写了如下一个DEMO程序,该DEMO程序包含的功能有:

    1:调用.NET2.0的MAKECERT创建含有私钥的数字证书,并存储到个人证书区;

    2:将该证书导出为pfx文件,并为其指定一个用来打开pfx文件的password;

    3:读取pfx文件,导出pfx中公钥和私钥;

    4:用pfx证书中的公钥进行数据的加密,用私钥进行数据的解密;

    代码如下:

    code 
    /// <summary>   
            
    /// 将证书从证书存储区导出,并存储为pfx文件,同时为pfx文件指定打开的密码   
            
    /// 本函数同时也演示如何用公钥进行加密,私钥进行解密   
            
    /// </summary>   
            
    /// <param name="sender"></param>   
            
    /// <param name="e"></param>   
            private void btn_toPfxFile_Click(object sender, EventArgs e)   
            {   
                X509Store store 
    = new X509Store(StoreName.My, StoreLocation.CurrentUser);   
                store.Open(OpenFlags.ReadWrite);   
                X509Certificate2Collection storecollection 
    = (X509Certificate2Collection)store.Certificates;   
                
    foreach (X509Certificate2 x509 in storecollection)   
                {   
                    
    if (x509.Subject == "CN=luminji")   
                    {   
                        Debug.Print(
    string.Format("certificate name: {0}", x509.Subject));   
                        
    byte[] pfxByte = x509.Export(X509ContentType.Pfx, "123");   
                        
    using (FileStream  fileStream = new FileStream("luminji.pfx", FileMode.Create))   
                        {   
                            
    // Write the data to the file, byte by byte.   
                            for (int i = 0; i < pfxByte.Length; i++)   
                                fileStream.WriteByte(pfxByte[i]);   
                            
    // Set the stream position to the beginning of the file.   
                            fileStream.Seek(0, SeekOrigin.Begin);   
                            
    // Read and verify the data.   
                            for (int i = 0; i < fileStream.Length; i++)   
                            {   
                                
    if (pfxByte[i] != fileStream.ReadByte())   
                                {   
                                    Debug.Print(
    "Error writing data.");   
                                    
    return;   
                                }   
                            }   
                            fileStream.Close();   
                            Debug.Print(
    "The data was written to {0} " +   
                                
    "and verified.", fileStream.Name);   
                        }   
                        
    string myname = "my name is luminji! and i love huzhonghua!";   
                        
    string enStr = this.RSAEncrypt(x509.PublicKey.Key.ToXmlString(false), myname);   
                        MessageBox.Show(
    "密文是:" + enStr);   
                        
    string deStr = this.RSADecrypt(x509.PrivateKey.ToXmlString(true), enStr);   
                        MessageBox.Show(
    "明文是:" + deStr);   
                    }   
                }   
                store.Close();   
                store 
    = null;   
                storecollection 
    = null;   
            }   
            
    /// <summary>   
            
    /// 创建还有私钥的证书   
            
    /// </summary>   
            
    /// <param name="sender"></param>   
            
    /// <param name="e"></param>   
            private void btn_createPfx_Click(object sender, EventArgs e)   
            {   
                
    string MakeCert = "C:\\Program Files\\Microsoft Visual Studio 8\\SDK\\v2.0\\Bin\\makecert.exe";   
                
    string x509Name = "CN=luminji";   
                
    string param = " -pe -ss my -n \"" + x509Name + "\" " ;   
                Process p 
    = Process.Start(MakeCert, param);   
                p.WaitForExit();   
                p.Close();   
                MessageBox.Show(
    "over");   
            }   
            
    /// <summary>   
            
    /// 从pfx文件读取证书信息   
            
    /// </summary>   
            
    /// <param name="sender"></param>   
            
    /// <param name="e"></param>   
            private void btn_readFromPfxFile(object sender, EventArgs e)   
            {   
                X509Certificate2 pc 
    = new X509Certificate2("luminji.pfx""123");   
                MessageBox.Show(
    "name:" + pc.SubjectName.Name);   
                MessageBox.Show(
    "public:" + pc.PublicKey.ToString());   
                MessageBox.Show(
    "private:" + pc.PrivateKey.ToString());   
                pc 
    = null;   
            }   
            
    /// <summary>   
            
    /// RSA解密   
            
    /// </summary>   
            
    /// <param name="xmlPrivateKey"></param>   
            
    /// <param name="m_strDecryptString"></param>   
            
    /// <returns></returns>   
            public string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)   
            {   
                RSACryptoServiceProvider provider 
    = new RSACryptoServiceProvider();   
                provider.FromXmlString(xmlPrivateKey);   
                
    byte[] rgb = Convert.FromBase64String(m_strDecryptString);   
                
    byte[] bytes = provider.Decrypt(rgb, false);   
                
    return new UnicodeEncoding().GetString(bytes);   
            }   
            
    /// <summary>   
            
    /// RSA加密   
            
    /// </summary>   
            
    /// <param name="xmlPublicKey"></param>   
            
    /// <param name="m_strEncryptString"></param>   
            
    /// <returns></returns>   
            public string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)   
            {   
                RSACryptoServiceProvider provider 
    = new RSACryptoServiceProvider();   
                provider.FromXmlString(xmlPublicKey);   
                
    byte[] bytes = new UnicodeEncoding().GetBytes(m_strEncryptString);   
                
    return Convert.ToBase64String(provider.Encrypt(bytes, false));   
            }  

    上文是一个示例程序,一个完整的证书工具类如下:

     
    code 
      1 ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
      2 public sealed class DataCertificate  
      3     {  
      4         #region 生成证书  
      5         /// <summary>  
      6         /// 根据指定的证书名和makecert全路径生成证书(包含公钥和私钥,并保存在MY存储区)  
      7         /// </summary>  
      8         /// <param name="subjectName"></param>  
      9         /// <param name="makecertPath"></param>  
     10         /// <returns></returns>  
     11         public static bool CreateCertWithPrivateKey(string subjectName, string makecertPath)  
     12         {  
     13             subjectName = "CN=" + subjectName;  
     14             string param = " -pe -ss my -n \"" + subjectName + "\" ";  
     15             try  
     16             {  
     17                 Process p = Process.Start(makecertPath, param);  
     18                 p.WaitForExit();  
     19                 p.Close();  
     20             }  
     21             catch (Exception e)  
     22             {  
     23                 LogRecord.putErrorLog(e.ToString(), "DataCerficate.CreateCertWithPrivateKey");  
     24                 return false;  
     25             }  
     26             return true;  
     27         }  
     28         #endregion  
     29  
     30         #region 文件导入导出  
     31         /// <summary>  
     32         /// 从WINDOWS证书存储区的个人MY区找到主题为subjectName的证书,  
     33         /// 并导出为pfx文件,同时为其指定一个密码  
     34         /// 并将证书从个人区删除(如果isDelFromstor为true)  
     35         /// </summary>  
     36         /// <param name="subjectName">证书主题,不包含CN=</param>  
     37         /// <param name="pfxFileName">pfx文件名</param>  
     38         /// <param name="password">pfx文件密码</param>  
     39         /// <param name="isDelFromStore">是否从存储区删除</param>  
     40         /// <returns></returns>  
     41         public static bool ExportToPfxFile(string subjectName, string pfxFileName,  
     42             string password, bool isDelFromStore)  
     43         {  
     44             subjectName = "CN=" + subjectName;  
     45             X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);  
     46             store.Open(OpenFlags.ReadWrite);  
     47             X509Certificate2Collection storecollection = (X509Certificate2Collection)store.Certificates;  
     48             foreach (X509Certificate2 x509 in storecollection)  
     49             {  
     50                 if (x509.Subject == subjectName)  
     51                 {  
     52                     Debug.Print(string.Format("certificate name: {0}", x509.Subject));  
     53   
     54                     byte[] pfxByte = x509.Export(X509ContentType.Pfx, password);  
     55                     using (FileStream fileStream = new FileStream(pfxFileName, FileMode.Create))  
     56                     {  
     57                         // Write the data to the file, byte by byte.  
     58                         for (int i = 0; i < pfxByte.Length; i++)  
     59                             fileStream.WriteByte(pfxByte[i]);  
     60                         // Set the stream position to the beginning of the file.  
     61                         fileStream.Seek(0, SeekOrigin.Begin);  
     62                         // Read and verify the data.  
     63                         for (int i = 0; i < fileStream.Length; i++)  
     64                         {  
     65                             if (pfxByte[i] != fileStream.ReadByte())  
     66                             {  
     67                                 LogRecord.putErrorLog("Export pfx error while verify the pfx file!""ExportToPfxFile");  
     68                                 fileStream.Close();  
     69                                 return false;  
     70                             }  
     71                         }  
     72                         fileStream.Close();  
     73                     }  
     74                     if( isDelFromStore == true)  
     75                         store.Remove(x509);  
     76                 }  
     77             }  
     78             store.Close();  
     79             store = null;  
     80             storecollection = null;  
     81             return true;  
     82         }  
     83         /// <summary>  
     84         /// 从WINDOWS证书存储区的个人MY区找到主题为subjectName的证书,  
     85         /// 并导出为CER文件(即,只含公钥的)  
     86         /// </summary>  
     87         /// <param name="subjectName"></param>  
     88         /// <param name="cerFileName"></param>  
     89         /// <returns></returns>  
     90         public static bool ExportToCerFile(string subjectName, string cerFileName)  
     91         {  
     92             subjectName = "CN=" + subjectName;  
     93             X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);  
     94             store.Open(OpenFlags.ReadWrite);  
     95             X509Certificate2Collection storecollection = (X509Certificate2Collection)store.Certificates;  
     96             foreach (X509Certificate2 x509 in storecollection)  
     97             {  
     98                 if (x509.Subject == subjectName)  
     99                 {  
    100                     Debug.Print(string.Format("certificate name: {0}", x509.Subject));  
    101                     //byte[] pfxByte = x509.Export(X509ContentType.Pfx, password);  
    102                     byte[] cerByte = x509.Export(X509ContentType.Cert);  
    103                     using (FileStream fileStream = new FileStream(cerFileName, FileMode.Create))  
    104                     {  
    105                         // Write the data to the file, byte by byte.  
    106                         for (int i = 0; i < cerByte.Length; i++)  
    107                             fileStream.WriteByte(cerByte[i]);  
    108                         // Set the stream position to the beginning of the file.  
    109                         fileStream.Seek(0, SeekOrigin.Begin);  
    110                         // Read and verify the data.  
    111                         for (int i = 0; i < fileStream.Length; i++)  
    112                         {  
    113                             if (cerByte[i] != fileStream.ReadByte())  
    114                             {  
    115                                 LogRecord.putErrorLog("Export CER error while verify the CERT file!""ExportToCERFile");  
    116                                 fileStream.Close();  
    117                                 return false;  
    118                             }  
    119                         }  
    120                         fileStream.Close();  
    121                     }  
    122                 }  
    123             }  
    124             store.Close();  
    125             store = null;  
    126             storecollection = null;  
    127             return true;  
    128         }  
    129         #endregion  
    130  
    131         #region 从证书中获取信息  
    132         /// <summary>  
    133         /// 根据私钥证书得到证书实体,得到实体后可以根据其公钥和私钥进行加解密  
    134         /// 加解密函数使用DEncrypt的RSACryption类  
    135         /// </summary>  
    136         /// <param name="pfxFileName"></param>  
    137         /// <param name="password"></param>  
    138         /// <returns></returns>  
    139         public static X509Certificate2 GetCertificateFromPfxFile(string pfxFileName,  
    140             string password)  
    141         {  
    142             try  
    143             {  
    144                 return new X509Certificate2(pfxFileName, password, X509KeyStorageFlags.Exportable);  
    145             }  
    146             catch (Exception e)  
    147             {  
    148                 LogRecord.putErrorLog("get certificate from pfx" + pfxFileName + " error:" + e.ToString(),  
    149                     "GetCertificateFromPfxFile");  
    150                 return null;  
    151             }  
    152         }  
    153         /// <summary>  
    154         /// 到存储区获取证书  
    155         /// </summary>  
    156         /// <param name="subjectName"></param>  
    157         /// <returns></returns>  
    158         public static X509Certificate2 GetCertificateFromStore(string subjectName)  
    159         {  
    160             subjectName = "CN=" + subjectName;  
    161             X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);  
    162             store.Open(OpenFlags.ReadWrite);  
    163             X509Certificate2Collection storecollection = (X509Certificate2Collection)store.Certificates;  
    164             foreach (X509Certificate2 x509 in storecollection)  
    165             {  
    166                 if (x509.Subject == subjectName)  
    167                 {  
    168                     return x509;  
    169                 }  
    170             }  
    171             store.Close();  
    172             store = null;  
    173             storecollection = null;  
    174             return null;  
    175         }  
    176         /// <summary>  
    177         /// 根据公钥证书,返回证书实体  
    178         /// </summary>  
    179         /// <param name="cerPath"></param>  
    180         public static X509Certificate2 GetCertFromCerFile(string cerPath)  
    181         {  
    182             try  
    183             {  
    184                 return new X509Certificate2(cerPath);  
    185             }  
    186             catch (Exception e)  
    187             {  
    188                 LogRecord.putErrorLog(e.ToString(), "DataCertificate.LoadStudentPublicKey");  
    189                 return null;  
    190             }              
    191         }  
    192         #endregion         
    193     }  
    194 
    转自:http://blog.csdn.net/luminji/archive/2009/03/05/3960308.aspx
  • 相关阅读:
    微信分享相关
    移动端界面适配
    MongoDB安装使用
    MongoDB可视化工具RoboMongo
    PhotoSwipe图片展示插件
    BootStrap下拉框搜索功能
    Node.js 特点
    原生node实现本地静态页面的展示
    阿里巴巴电话初面
    react动态添加多个输入框
  • 原文地址:https://www.cnblogs.com/NoRoad/p/1675866.html
Copyright © 2011-2022 走看看