(一)简介
 最早、最著名的保密密钥或对称密钥加密算法DES(Data Encryption Standard)是由IBM公司在70年代发展起来的,并经政府的加密标准筛选后,于1976年11月被美国政府采用,DES随后被美国国家标准局和美国国家标准协会(American National Standard Institute,ANSI)承认。    DES使用56位密钥对64位的数据块进行加密,并对64位的数据块进行16轮编码。与每轮编码时,一个48位的"每轮"密钥值由56位的完整密钥得出来。DES用软件进行解码需用很长时间,而用硬件解码速度非常快。幸运的是,当时大多数黑客并没有足够的设备制造出这种硬件设备。在1977年,人们估计要耗资两千万美元才能建成一个专门计算机用于DES的解密,而且需要12个小时的破解才能得到结果。当时DES被认为是一种十分强大的加密方法。
    随着计算机硬件的速度越来越快,制造一台这样特殊的机器的花费已经降到了十万美元左右,而用它来保护十亿美元的银行,那显然是不够保险了。另一方面,如果只用它来保护一台普通服务器,那么DES确实是一种好的办法,因为黑客绝不会仅仅为入侵一个服务器而花那么多的钱破解DES密文。
    另一种非常著名的加密算法就是RSA了,RSA(Rivest-Shamir-Adleman)算法是基于大数不可能被质因数分解假设的公钥体系。简单地说就是找两个很大的质数。一个对外公开的为“公钥”(Public key) ,另一个不告诉任何人,称为"私钥”(Private key)。这两个密钥是互补的,也就是说用公钥加密的密文可以用私钥解密,反过来也一样。
    假设用户甲要寄信给用户乙,他们互相知道对方的公钥。甲就用乙的公钥加密邮件寄出,乙收到后就可以用自己的私钥解密出甲的原文。由于别人不知道乙的私钥,所以即使是甲本人也无法解密那封信,这就解决了信件保密的问题。另一方面,由于每个人都知道乙的公钥,他们都可以给乙发信,那么乙怎么确信是不是甲的来信呢?那就要用到基于加密技术的数字签名了。
    甲用自己的私钥将签名内容加密,附加在邮件后,再用乙的公钥将整个邮件加密(注意这里的次序,如果先加密再签名的话,别人可以将签名去掉后签上自己的签名,从而篡改了签名)。这样这份密文被乙收到以后,乙用自己的私钥将邮件解密,得到甲的原文和数字签名,然后用甲的公钥解密签名,这样一来就可以确保两方面的安全了。
加密
| //////////////////////////          //加密函数          public string EncryptData(String strKey, String strData)          {               string strResult;      //返回值               //1. 字符串长度不能超过90kb,否则,内存将溢出,看3就知道原因               if (strData.Length > 92160)               {                    strResult="Error. Data String too large. Keep within 90Kb.";                    return strResult;               }                         //2. 发生密码               if (!InitKey(strKey))               {                    strResult="Error. Fail to generate key for encryption";                    return strResult;               }               //3. 准备字符串               //   字符串的头5个字符将被格式化后存储数据的实际长度.               //   这是最简单的方法来记住数据的初始长度,不借助于复杂的计算.               strData = String.Format("{0,5:00000}"+strData, strData.Length);               //4. 加密数据               byte[] rbData = new byte[strData.Length];               ASCIIEncoding aEnc = new ASCIIEncoding();               aEnc.GetBytes(strData, 0, strData.Length, rbData, 0);                              DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();                               ICryptoTransform desEncrypt = descsp.CreateEncryptor(m_Key, m_IV);                //5. 流:               //   mOut 是输出流.                //   mStream 是输入流.               //   cs 是转换流               MemoryStream mStream = new MemoryStream(rbData);                CryptoStream cs = new CryptoStream(mStream, desEncrypt, CryptoStreamMode.Read);                       MemoryStream mOut = new MemoryStream();                              //6. 开始实施加密               int bytesRead;                byte[] output = new byte[1024];                do                {                     bytesRead = cs.Read(output,0,1024);                    if (bytesRead != 0)                         mOut.Write(output,0,bytesRead);                } while (bytesRead > 0);                               //7. 返回加密结果在base64编码之后               //   在这种情况,实际结果是转换成base64编码以至它能被HTTP协议传输而不发生损坏.               if (mOut.Length == 0)                           strResult = "";               else                    strResult = Convert.ToBase64String(mOut.GetBuffer(), 0, (int)mOut.Length);                         return strResult;          } | 
解密
| 
          //解密函数          public string DecryptData(String strKey, String strData)          {               string strResult;               //1. 用来解密的密钥               if (!InitKey(strKey))               {                    strResult="Error. Fail to generate key for decryption";                    return strResult;               }               //2. 提供初始化服务               int nReturn = 0;               DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();                ICryptoTransform desDecrypt = descsp.CreateDecryptor(m_Key, m_IV);                               //3. 预备流:               //   mOut 是输出流.                //   cs 是转换流.               MemoryStream mOut = new MemoryStream();               CryptoStream cs = new CryptoStream(mOut, desDecrypt, CryptoStreamMode.Write);                                      //4. 记着将base64编码恢复到到字节数组存在最初的数据流               byte[] bPlain = new byte[strData.Length];               try                {                    bPlain = Convert.FromBase64CharArray(strData.ToCharArray(), 0, strData.Length);               }               catch (Exception)                {                     strResult = "Error. Input Data is not base64 encoded.";                    return strResult;               }                              long lRead = 0;               long lTotal = strData.Length;                              try               {                    //5. 实施解码                    while (lTotal >= lRead)                    {                         cs.Write(bPlain,0,(int)bPlain.Length);                         //descsp.BlockSize=64                        lRead = mOut.Length + Convert.ToUInt32(((bPlain.Length / descsp.BlockSize) * descsp.BlockSize));                    };                                        ASCIIEncoding aEnc = new ASCIIEncoding();                    strResult = aEnc.GetString(mOut.GetBuffer(), 0, (int)mOut.Length);                                        //6. 将字符串整齐化,返回成只含有有实际意义的数据                    //   记着在加密函数中,头5个字符指示了实际数据的长度                    //   这是最简单的方法来记着最初数据的长度,不用借助任何复杂的计算                    String strLen = strResult.Substring(0,5);                    int nLen = Convert.ToInt32(strLen);                    strResult = strResult.Substring(5, nLen);                    nReturn = (int)mOut.Length;                                        return strResult;               }               catch (Exception)               {                    strResult = "Error. Decryption Failed. Possibly due to incorrect Key or corrputed data";                    return strResult;               }          } | 
KEY
|          /////////////////////////////////////////////////////////////          //私有函数将生成keys成为成员变量          static private bool InitKey(String strKey)          {               try               {                    // 将key转换成字节数组                    byte[] bp = new byte[strKey.Length];                    ASCIIEncoding aEnc = new ASCIIEncoding();                    aEnc.GetBytes(strKey, 0, strKey.Length, bp, 0);                                        //用SHA1来哈希key                    SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();                    byte[] bpHash = sha.ComputeHash(bp);                                        int i;                    // 使用低64位作为key值                    for (i=0; i<8; i++)                         m_Key[i] = bpHash[i];                                            for (i=8; i<16; i++)                         m_IV[i-8] = bpHash[i];                                        return true;               }               catch (Exception)               {                    //错误操作                    return false;               }          } | 
调用
| FE_Symmetric Crypt;               Crypt = new FE_Symmetric();               string tempAddress =textBox1.Text;                             this.textBox2.Text = Crypt.EncryptData("42", tempAddress);      //提供服务方加密过程,得到sn,显示在textBox2中              this.textBox2.Text = Crypt. DecryptData("42", tempAddress);              | 
一定要先加密再解密,而且加密和解密的密码要一样!
 
                     
                    
                 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号