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

你可能感兴趣的:(数字证书)