[转]加解密技术

先明确一下概念:  
  公钥加密私钥解密,   没问题,也可以说是"公共密钥加密系统"  
  私钥加密公钥解密,一般不这么说,应叫"私钥签名,公钥验证",也可以说是“公共密钥签名系统”  
   
  再来说一下"公共密钥签名系统"目的:(如果晕就多看几遍,这个没搞清,后面的代码就更晕)  
   
  A欲传(信息)给B,但又怕B不确信该信息是A发的。  
  1.A选计算(信息)的HASH值,如用MD5方式计算,得到:[MD5(信息)]  
  2.然后用自已的私钥加密HASH值,得到:[私钥(MD5(信息))]  
  3.最后将信息与密文一起传给B:传给B:[(信息)   +   私钥(MD5(信息))]  
   
  B接到   :[(信息)   +   私钥(MD5(信息))]  
  1.先用相同的HASH算法算出(信息)的HASH值,这里也使用MD5方式    
  得到:   [MD5(信息)!]  
  2.   再用A的公钥解密   [   私钥(MD5(信息))]  
        [公钥(私钥(MD5(信息)))]   =   [(MD5(信息)]  
        如能解开,证明该   [   私钥(MD5(信息))]是A发送的  
  3.再比效[MD5(信息)!]与[(MD5(信息)]  
        如果相同,表示(信息)在传递过程中没有被他人修改过  


私钥签名的代码:  
                   
                  '在C盘上在有[keys.xml(密钥文件,包括公钥与私钥)]文件  
                  '与[原文件.txt(要签名的信息文件)]文件  
                  '-------------------------------------------------------------  
   
   
                  '------------MD5要签名的磁盘文件-----------------------------------  
                  '定义一个文件流,以打开要签名的磁盘文件  
                  Dim   文件流   As   New   System.IO.FileStream("C:\原文件.txt",   IO.FileMode.Open)  
   
                  '定义一个字节数组以存入文件流  
                  Dim   文件流数组(文件流.Length   -   1)   As   Byte  
   
                  '将文件流存入文件数组  
                  文件流.Read(文件流数组,   0,   文件流.Length)  
   
                  '建立MD5对象  
                  Dim   MD5对象   As   New   System.Security.Cryptography.MD5CryptoServiceProvider  
                  '得到字节数组格式的MD5值  
                  Dim   MD5值数组()   As   Byte   =   MD5对象.ComputeHash(文件流数组)  
                  文件流.Close()   '关闭文件流  
                  '------------------------END----------------------------------------  
   
   
                  '----------加载私钥------------------------------------------------  
   
                  '加载XML密钥文件,该文件包含公钥与私钥,本程序使用私钥签名  
   
                  Dim   KeyFile   As   New   IO.FileStream("c:\keys.xml",   IO.FileMode.Open)  
   
                  '定义一个文本流  
                  Dim   KeyFileData   As   New   IO.StreamReader(KeyFile,   System.Text.UTF8Encoding.UTF8)  
   
                  '定义一个字符变量用于读取XML文件的文本流  
                  Dim   KeyString   As   String   =   KeyFileData.ReadToEnd  
   
                  KeyFileData.Close()   '关闭文本流  
                  KeyFile.Close()           '关闭文件流  
                  '--------------------------END---------------------------------------  
   
                  '------------------用私钥加密MD5数据---------------------------------  
                  '定义RSA对象  
                  Dim   rsa   As   New   System.Security.Cryptography.RSACryptoServiceProvider  
   
                  'RSA对象加载密钥文件XML格式的字符串  
                  rsa.FromXmlString(KeyString)  
   
                  '定义一个BYTE数组,用于存放加密信息  
                  Dim   签名()   As   Byte  
   
                  '得到加密信息的二进制数组数据  
                  签名   =   rsa.SignHash(MD5值数组,   CryptoConfig.MapNameToOID("MD5"))  
                  '--------------------------END---------------------------------------  
   
                  '---------将该二进制数组数据存入磁盘文件------------------------------  
   
                  Dim   签名数据   As   New   IO.FileStream("c:\签名信息.byte",   IO.FileMode.Create)  
                  签名数据.Write(签名,   0,   签名.Length)  
                  签名数据.Close()  
                  '--------------------------END---------------------------------------  
  =========================================================================  
  公钥验证:  
                  '在C盘上在有[Pubkey.xml(公钥文件)]文件  
                  '与[新文件.txt(要验证的信息文件)]文件  
                  '与[签名信息.byte(签名信息文件)]文件  
                  '-------------------------------------------------------------  
   
   
   
                  '-----------载入签名信息文件------------------------------------------  
                  '定义一个文件流,以打开要签名的磁盘文件  
                  Dim   签名信息文件   As   New   System.IO.FileStream("C:\签名信息.byte",   IO.FileMode.Open)  
   
                  '定义一个字节数组以存入文件流  
                  Dim   签名信息数组(签名信息文件.Length   -   1)   As   Byte  
   
                  '将文件流存入文件数组  
                  签名信息文件.Read(签名信息数组,   0,   签名信息文件.Length)  
   
                  签名信息文件.Close()  
                  '--------------------------END---------------------------------------  
   
   
                  '------------MD5要验证的磁盘文件-----------------------------------  
                  '定义一个文件流,以打开要签名的磁盘文件  
                  '如果[新文件.txt]的内容与[原文件.txt]一样将在最后显示True,不一样将为False  
                  Dim   文件流   As   New   System.IO.FileStream("C:\新文件.txt",   IO.FileMode.Open)  
   
                  '定义一个字节数组以存入文件流  
                  Dim   文件流数组(文件流.Length   -   1)   As   Byte  
   
                  '将文件流存入文件数组  
                  文件流.Read(文件流数组,   0,   文件流.Length)  
   
                  '建立MD5对象  
                  Dim   MD5对象   As   New   System.Security.Cryptography.MD5CryptoServiceProvider  
                  '得到字节数组格式的MD5值  
                  Dim   MD5值数组()   As   Byte   =   MD5对象.ComputeHash(文件流数组)  
                  文件流.Close()   '关闭文件流  
                  '------------------------END----------------------------------------  
   
                  '----------加载公钥------------------------------------------------  
   
                  '加载XML公钥文件,该文件只包含公钥  
   
                  Dim   KeyFile   As   New   IO.FileStream("c:\Pubkey.xml",   IO.FileMode.Open)  
   
                  '定义一个文本流  
                  Dim   KeyFileData   As   New   IO.StreamReader(KeyFile,   System.Text.UTF8Encoding.UTF8)  
   
                  '定义一个字符变量用于读取XML文件的文本流  
                  Dim   KeyString   As   String   =   KeyFileData.ReadToEnd  
   
                  KeyFileData.Close()   '关闭文本流  
                  KeyFile.Close()           '关闭文件流  
                  '--------------------------END---------------------------------------  
   
                  '------------------用公钥解密MD5数据---------------------------------  
                  '定义RSA对象  
                  Dim   rsa   As   New   System.Security.Cryptography.RSACryptoServiceProvider  
   
                  'RSA对象加载密钥文件XML格式的字符串  
                  rsa.FromXmlString(KeyString)  
   
                  Dim   值   As   Boolean  
   
                  '如果为真表示文件验证通过  
                  值   =   rsa.VerifyHash(MD5值数组,   CryptoConfig.MapNameToOID("MD5"),   签名信息数组)  
   
                  MsgBox(值)  

 

DES加密类,公钥和私钥可以通过工具(Sn.exe)生成  
   
  #region     des加密算法  
        ///   <summary>  
        ///   加密字符串  
        ///   </summary>  
        ///   <param   name="pToEncrypt">待加密字符串</param>  
        ///   <returns></returns>  
        public   string   Encrypt(string   pToEncrypt)  
        {    
   
          byte[]   desKey   =   new     byte[]{0x16,   0x09,   0x14,   0x15,   0x07,   0x01,   0x05,   0x08};  
          byte[]   desIV   =   new     byte[]{0x16,   0x09,   0x14,   0x15,   0x07,   0x01,   0x05,   0x08};  
   
          DESCryptoServiceProvider   des   =   new   DESCryptoServiceProvider();  
          try  
          {  
            //把字符串放到byte数组中  
            //原来使用的UTF8编码,我改成Unicode编码了,不行  
            byte[]   inputByteArray   =   Encoding.Default.GetBytes(pToEncrypt);  
            //byte[]   inputByteArray=Encoding.Unicode.GetBytes(pToEncrypt);  
   
            //建立加密对象的密钥和偏移量  
            //原文使用ASCIIEncoding.ASCII方法的GetBytes方法  
            //使得输入密码必须输入英文文本  
            des.Key   =   desKey;     //   ASCIIEncoding.ASCII.GetBytes(sKey);  
            des.IV   =   desIV;       //ASCIIEncoding.ASCII.GetBytes(sKey);  
            MemoryStream   ms   =   new   MemoryStream();  
            CryptoStream   cs   =   new   CryptoStream(ms,   des.CreateEncryptor(),  
              CryptoStreamMode.Write);  
            //Write   the   byte   array   into   the   crypto   stream  
            //(It   will   end   up   in   the   memory   stream)  
            cs.Write(inputByteArray,   0,   inputByteArray.Length);  
            cs.FlushFinalBlock();  
   
            //Get   the   data   back   from   the   memory   stream,   and   into   a   string  
            StringBuilder   ret   =   new   StringBuilder();  
            foreach(byte   b   in   ms.ToArray())  
            {  
              //Format   as   hex  
              ret.AppendFormat("{0:X2}",   b);  
            }  
            ret.ToString();  
            return   ret.ToString();  
          }  
          catch  
          {  
            return   pToEncrypt;  
          }  
          finally  
          {  
            des   =   null;  
          }  
        }  
   
        ///   <summary>  
        ///   解密字符串  
        ///   </summary>  
        ///   <param   name="pToDecrypt">待解密字符串</param>  
        ///   <returns></returns>  
        public   string   Decrypt(string   pToDecrypt)        
        {  
          byte[]   desKey   =   new     byte[]{0x16,   0x09,   0x14,   0x15,   0x07,   0x01,   0x05,   0x08};  
          byte[]   desIV   =   new     byte[]{0x16,   0x09,   0x14,   0x15,   0x07,   0x01,   0x05,   0x08};  
   
          DESCryptoServiceProvider   des   =   new   DESCryptoServiceProvider();  
          try  
          {  
            //Put   the   input   string   into   the   byte   array  
            byte[]   inputByteArray   =   new   byte[pToDecrypt.Length   /   2];  
            for(int   x   =   0;   x   <   pToDecrypt.Length   /   2;   x++)  
            {  
              int   i   =   (Convert.ToInt32(pToDecrypt.Substring(x   *   2,   2),   16));  
              inputByteArray[x]   =   (byte)i;  
            }  
   
            //建立加密对象的密钥和偏移量,此值重要,不能修改  
            des.Key   =   desKey;       //ASCIIEncoding.ASCII.GetBytes(sKey);  
            des.IV   =   desIV;         //ASCIIEncoding.ASCII.GetBytes(sKey);  
            MemoryStream   ms   =   new   MemoryStream();  
            CryptoStream   cs   =   new   CryptoStream(ms,   des.CreateDecryptor(),CryptoStreamMode.Write);  
            //Flush   the   data   through   the   crypto   stream   into   the   memory   stream  
            cs.Write(inputByteArray,   0,   inputByteArray.Length);  
            cs.FlushFinalBlock();  
   
            //Get   the   decrypted   data   back   from   the   memory   stream  
            //建立StringBuild对象,CreateDecrypt使用的是流对象,必须把解密后的文本变成流对象  
            StringBuilder   ret   =   new   StringBuilder();  
     
            return   System.Text.Encoding.Default.GetString(ms.ToArray());  
          }  
          catch  
          {  
            return   pToDecrypt;    
          }  
          finally  
          {  
            des   =   null;  
          }  
        }  
   
        #endregion    
   

 

posted @ 2009-10-10 10:10  孤城浪子  阅读(288)  评论(0编辑  收藏  举报
博客园,让我更上一层楼