admin 管理员组

文章数量: 887007

.net加密解密

加密与解密概述

加密与解密属于数据安全的范畴。在消息传输时,通过对消息进行特殊编码(加密),建立一种安全的交流方式,使得只有发送者所期望的接收者能够理解 (解密)。这里我们定义一个场景:发送方,接收方,第三方,发送方要将信息发送给接收方,二第三方想要截取并篡改消息,然后在转发给接收方。要称得上是安 全的交流方式,需要满足下面的3个条件:

  1. 完整性,消息的接收方可以确定消息在传输过程中没有被篡改过,即消息是完好无损。
  2. 保密性,第三方无法解密发送的消息(第三方可以获取传输的消息)。
  3. 可认证性,即接收方可以知道消息是由谁发送的。

下面将列出几种常用的技术,看看是否符合上面的3个条件。

散列运算

散列(英语:Hashing)是电脑科学中一种对资料的处理方法,通过某种特定的函数/算法(称为散列函数/算法)将要检索的项与用来检索的索引 (称为散列,或者散列值)关联起来,生成一种便于搜索的数据结构(称为散列表)。也译为散列。旧译哈希(误以为是人名而采用了音译)。它也常用作一种资讯 安全的实作方法,由一串资料中经过散列算法(Hashing algorithms)计算出来的资料指纹(data fingerprint),经常用来识别档案与资料是否有被窜改,以保证档案与资料确实是由原创者所提供。
如今,散列算法也被用来加密存在数据库 中的密码(password)字串,由于散列算法所计算出来的散列值(Hash Value)具有不可逆(无法逆向演算回原本的数值)的性质,因此可有效的保护密码,我公司内的Web管理系统存储的密码字符串就是散列运算的摘要,确实 很实用。

散列运算具有以下3个特点:

  1. 散列运算是不可逆的(加密是单向的)。
  2. 任何两个不相同文件的摘要是不同的。
  3. 不论原始消息大小如何,同一种散列算法得到的摘要的长度是固定的。

常见的散列运算如下图所示:

由此可见散列算法只能满足完整性的条件。

对称加密

对称密钥加密(英语:Symmetric-key algorithm)又称为对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单 地相互推算的密钥。实务上,这组密钥成为在两个或多个成员间的共同秘密,以便维持专属的通讯联系。与公开密钥加密相比,要求双方取得相同的密钥是对称密钥 加密的主要缺点之一。

常见的对称加密算法有DES、3DES、AES、Blowfish、IDEA、RC5、RC6。

对称加密流程如下:

  1. 发送方和接收方吃有相同的密钥并严格保密。
  2. 发送方使用密钥对消息进行加密,然后发送消息。
  3. 接收方接收到消息使用同样能够的密钥进行解密。
  4. 在这一过程中第三方截取到消息,但得到的只是一堆乱码。

由此可见,对称加密可以解决保密的问题,但是要确保第三方没有非法获取到密钥。

非对称加密

非对称加密(asymmetric cryptography),又称为公开密钥加密(英语:public-key cryptography),在这种密码学方法中,需要一对密钥,一是个私人密钥,另一个则是公开密钥。这两个密钥是数学相关,用某用户密钥加密后所得的 信息,只能用该用户的解密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个的秘密性质。 称公开的密钥为公钥;不公开的密钥为私钥。
如果加密密钥是公开的,这用于客户给私钥所有者上传加密的数据,这被称作为公开密钥加密(狭义)。例如,网络银行的客户发给银行网站的账户操作的加密数据。

如果解密密钥是公开的,用私钥加密的信息,可以用公钥对其解密,用于客户验证持有私钥一方发布的数据或文件是完整准确的,接收者由此可知这条信息确 实来自于拥有私钥的某人,这被称作数字签名,公钥的形式就是数字证书。例如,从网上下载的安装程序,一般都带有程序制作者的数字签名,可以证明该程序的确 是该作者(公司)发布的而不是第三方伪造的且未被篡改过(身份认证/验证)。

常见的公钥加密算法有: RSA、ElGamal、背包算法、Rabin(RSA的特例)、迪菲-赫尔曼密钥交换协议中的公钥加密算法、椭圆曲线加密算法(英语:Elliptic Curve Cryptography, ECC)。使用最广泛的是RSA算法(由发明者Rivest、Shmir和Adleman姓氏首字母缩写而来)是著名的公开金钥加密算法,ElGamal 是另一种常用的非对称加密算法。

现在假设这种加密方式只使用一组密钥对,根据使用发送方还是接收方的密钥对又可分为加密模式和认证模式。

加密模式下,由消息的接收方发布公钥,持有私钥。基本步骤如下所示:

  1. 接收方公布自己的公钥,任何人都可以获得。
  2. 发送方使用上述公钥对消息进行加密,然后发送。
  3. 接收方使用自己的私钥对消息进行解密。

可以看出非对称加密的加密模式可以解决保密性问题。

认证模式下,由消息的发送方发布公钥,持有私钥。基本步骤如下所示:

  1. 发送方公布自己的公钥,任何人都可以获得。
  2. 发送方使用自己的私钥对消息进行加密,然后发送。
  3. 接收方使用发送方的私钥对消息进行解密。

可以看出非对称加密的加密模式可以解决认证性问题。

得出结论

上面的技术单一使用无法全部满足完整、保密和认证的3个条件,但是通过组合使用的方式就可以达到目的了。比如说数字签名就是在上面的认证模式加上了散列运算。

加密解密类(苏飞论坛所有)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 /// <summary> /// 类说明:Assistant /// 编 码 人:苏飞 /// 联系方式:361983679  /// 更新网站:.html /// </summary> using System; using System.Text; using System.Security.Cryptography; using System.IO; using System.Text.RegularExpressions; using System.Collections; namespace DotNet.Utilities {      /// <summary>      /// MySecurity(安全类) 的摘要说明。      /// </summary>      public class MySecurity      {          /// <summary>          /// 初始化安全类          /// </summary>          public MySecurity()          {              ///默认密码              key = "0123456789" ;          }          private string key; //默认密钥          private byte [] sKey;          private byte [] sIV;          #region 加密字符串          /// <summary>          /// 加密字符串          /// </summary>          /// <param name="inputStr">输入字符串</param>          /// <param name="keyStr">密码,可以为“”</param>          /// <returns>输出加密后字符串</returns>          static public string SEncryptString( string inputStr, string keyStr)          {              MySecurity ws = new MySecurity();              return ws.EncryptString(inputStr, keyStr);          }          /// <summary>          /// 加密字符串          /// </summary>          /// <param name="inputStr">输入字符串</param>          /// <param name="keyStr">密码,可以为“”</param>          /// <returns>输出加密后字符串</returns>          public string EncryptString( string inputStr, string keyStr)          {              DESCryptoServiceProvider des = new DESCryptoServiceProvider();              if (keyStr == "" )                  keyStr = key;              byte [] inputByteArray = Encoding.Default.GetBytes(inputStr);              byte [] keyByteArray = Encoding.Default.GetBytes(keyStr);              SHA1 ha = new SHA1Managed();              byte [] hb = ha.ComputeHash(keyByteArray);              sKey = new byte [8];              sIV = new byte [8];              for ( int i = 0; i < 8; i++)                  sKey[i] = hb[i];              for ( int i = 8; i < 16; i++)                  sIV[i - 8] = hb[i];              des.Key = sKey;              des.IV = sIV;              MemoryStream ms = new MemoryStream();              CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);              cs.Write(inputByteArray, 0, inputByteArray.Length);              cs.FlushFinalBlock();              StringBuilder ret = new StringBuilder();              foreach ( byte b in ms.ToArray())              {                  ret.AppendFormat( "{0:X2}" , b);              }              cs.Close();              ms.Close();              return ret.ToString();          }          #endregion          #region 加密字符串 密钥为系统默认 0123456789          /// <summary>          /// 加密字符串 密钥为系统默认          /// </summary>          /// <param name="inputStr">输入字符串</param>          /// <returns>输出加密后字符串</returns>          static public string SEncryptString( string inputStr)          {              MySecurity ws = new MySecurity();              return ws.EncryptString(inputStr, "" );          }          #endregion          #region 加密文件          /// <summary>          /// 加密文件          /// </summary>          /// <param name="filePath">输入文件路径</param>          /// <param name="savePath">加密后输出文件路径</param>          /// <param name="keyStr">密码,可以为“”</param>          /// <returns></returns>           public bool EncryptFile( string filePath, string savePath, string keyStr)          {              DESCryptoServiceProvider des = new DESCryptoServiceProvider();              if (keyStr == "" )                  keyStr = key;              FileStream fs = File.OpenRead(filePath);              byte [] inputByteArray = new byte [fs.Length];              fs.Read(inputByteArray, 0, ( int )fs.Length);              fs.Close();              byte [] keyByteArray = Encoding.Default.GetBytes(keyStr);              SHA1 ha = new SHA1Managed();              byte [] hb = ha.ComputeHash(keyByteArray);              sKey = new byte [8];              sIV = new byte [8];              for ( int i = 0; i < 8; i++)                  sKey[i] = hb[i];              for ( int i = 8; i < 16; i++)                  sIV[i - 8] = hb[i];              des.Key = sKey;              des.IV = sIV;              MemoryStream ms = new MemoryStream();              CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);              cs.Write(inputByteArray, 0, inputByteArray.Length);              cs.FlushFinalBlock();              fs = File.OpenWrite(savePath);              foreach ( byte b in ms.ToArray())              {                  fs.WriteByte(b);              }              fs.Close();              cs.Close();              ms.Close();              return true ;          }          #endregion          #region 解密字符串          /// <summary>          /// 解密字符串          /// </summary>          /// <param name="inputStr">要解密的字符串</param>          /// <param name="keyStr">密钥</param>          /// <returns>解密后的结果</returns>          static public string SDecryptString( string inputStr, string keyStr)          {              MySecurity ws = new MySecurity();              return ws.DecryptString(inputStr, keyStr);          }          /// <summary>          ///  解密字符串 密钥为系统默认          /// </summary>          /// <param name="inputStr">要解密的字符串</param>          /// <returns>解密后的结果</returns>          static public string SDecryptString( string inputStr)          {              MySecurity ws = new MySecurity();              return ws.DecryptString(inputStr, "" );          }          /// <summary>          /// 解密字符串          /// </summary>          /// <param name="inputStr">要解密的字符串</param>          /// <param name="keyStr">密钥</param>          /// <returns>解密后的结果</returns>          public string DecryptString( string inputStr, string keyStr)          {              DESCryptoServiceProvider des = new DESCryptoServiceProvider();              if (keyStr == "" )                  keyStr = key;              byte [] inputByteArray = new byte [inputStr.Length / 2];              for ( int x = 0; x < inputStr.Length / 2; x++)              {                  int i = (Convert.ToInt32(inputStr.Substring(x * 2, 2), 16));                  inputByteArray[x] = ( byte )i;              }              byte [] keyByteArray = Encoding.Default.GetBytes(keyStr);              SHA1 ha = new SHA1Managed();              byte [] hb = ha.ComputeHash(keyByteArray);              sKey = new byte [8];              sIV = new byte [8];              for ( int i = 0; i < 8; i++)                  sKey[i] = hb[i];              for ( int i = 8; i < 16; i++)                  sIV[i - 8] = hb[i];              des.Key = sKey;              des.IV = sIV;              MemoryStream ms = new MemoryStream();              CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);              cs.Write(inputByteArray, 0, inputByteArray.Length);              cs.FlushFinalBlock();              StringBuilder ret = new StringBuilder();              return System.Text.Encoding.Default.GetString(ms.ToArray());          }          #endregion          #region 解密文件          /// <summary>          /// 解密文件          /// </summary>          /// <param name="filePath">输入文件路径</param>          /// <param name="savePath">解密后输出文件路径</param>          /// <param name="keyStr">密码,可以为“”</param>          /// <returns></returns>             public bool DecryptFile( string filePath, string savePath, string keyStr)          {              DESCryptoServiceProvider des = new DESCryptoServiceProvider();              if (keyStr == "" )                  keyStr = key;              FileStream fs = File.OpenRead(filePath);              byte [] inputByteArray = new byte [fs.Length];              fs.Read(inputByteArray, 0, ( int )fs.Length);              fs.Close();              byte [] keyByteArray = Encoding.Default.GetBytes(keyStr);              SHA1 ha = new SHA1Managed();              byte [] hb = ha.ComputeHash(keyByteArray);              sKey = new byte [8];              sIV = new byte [8];              for ( int i = 0; i < 8; i++)                  sKey[i] = hb[i];              for ( int i = 8; i < 16; i++)                  sIV[i - 8] = hb[i];              des.Key = sKey;              des.IV = sIV;              MemoryStream ms = new MemoryStream();              CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);              cs.Write(inputByteArray, 0, inputByteArray.Length);              cs.FlushFinalBlock();              fs = File.OpenWrite(savePath);              foreach ( byte b in ms.ToArray())              {                  fs.WriteByte(b);              }              fs.Close();              cs.Close();              ms.Close();              return true ;          }          #endregion          #region MD5加密          /// <summary>          /// 128位MD5算法加密字符串          /// </summary>          /// <param name="text">要加密的字符串</param>             public static string MD5( string text)          {              //如果字符串为空,则返回              if (Tools.IsNullOrEmpty< string >(text))              {                  return "" ;              }              //返回MD5值的字符串表示              return MD5(text);          }          /// <summary>          /// 128位MD5算法加密Byte数组          /// </summary>          /// <param name="data">要加密的Byte数组</param>             public static string MD5( byte [] data)          {              //如果Byte数组为空,则返回              if (Tools.IsNullOrEmpty< byte []>(data))              {                  return "" ;              }              try              {                  //创建MD5密码服务提供程序                  MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();                  //计算传入的字节数组的哈希值                  byte [] result = md5.ComputeHash(data);                  //释放资源                  md5.Clear();                  //返回MD5值的字符串表示                  return Convert.ToBase64String(result);              }              catch              {                  //LogHelper.WriteTraceLog(TraceLogLevel.Error, ex.Message);                  return "" ;              }          }          #endregion          #region Base64加密          /// <summary>          /// Base64加密          /// </summary>          /// <param name="text">要加密的字符串</param>          /// <returns></returns>          public static string EncodeBase64( string text)          {              //如果字符串为空,则返回              if (Tools.IsNullOrEmpty< string >(text))              {                  return "" ;              }              try              {                  char [] Base64Code = new char []{ 'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' , 'J' , 'K' , 'L' , 'M' , 'N' , 'O' , 'P' , 'Q' , 'R' , 'S' , 'T' ,                                              'U' , 'V' , 'W' , 'X' , 'Y' , 'Z' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,                                              'o' , 'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' , 'x' , 'y' , 'z' , '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' ,                                              '8' , '9' , '+' , '/' , '=' };                  byte empty = ( byte )0;                  ArrayList byteMessage = new ArrayList(Encoding.Default.GetBytes(text));                  StringBuilder outmessage;                  int messageLen = byteMessage.Count;                  int page = messageLen / 3;                  int use = 0;                  if ((use = messageLen % 3) > 0)                  {                      for ( int i = 0; i < 3 - use; i++)                          byteMessage.Add(empty);                      page++;                  }                  outmessage = new System.Text.StringBuilder(page * 4);                  for ( int i = 0; i < page; i++)                  {                      byte [] instr = new byte [3];                      instr[0] = ( byte )byteMessage[i * 3];                      instr[1] = ( byte )byteMessage[i * 3 + 1];                      instr[2] = ( byte )byteMessage[i * 3 + 2];                      int [] outstr = new int [4];                      outstr[0] = instr[0] >> 2;                      outstr[1] = ((instr[0] & 0x03) << 4) ^ (instr[1] >> 4);                      if (!instr[1].Equals(empty))                          outstr[2] = ((instr[1] & 0x0f) << 2) ^ (instr[2] >> 6);                      else                          outstr[2] = 64;                      if (!instr[2].Equals(empty))                          outstr[3] = (instr[2] & 0x3f);                      else                          outstr[3] = 64;                      outmessage.Append(Base64Code[outstr[0]]);                      outmessage.Append(Base64Code[outstr[1]]);                      outmessage.Append(Base64Code[outstr[2]]);                      outmessage.Append(Base64Code[outstr[3]]);                  }                  return outmessage.ToString();              }              catch (Exception ex)              {                  throw ex;              }          }          #endregion          #region Base64解密          /// <summary>          /// Base64解密          /// </summary>          /// <param name="text">要解密的字符串</param>          public static string DecodeBase64( string text)          {              //如果字符串为空,则返回              if (Tools.IsNullOrEmpty< string >(text))              {                  return "" ;              }              //将空格替换为加号              text = text.Replace( " " , "+" );              try              {                  if ((text.Length % 4) != 0)                  {                      return "包含不正确的BASE64编码" ;                  }                  if (!Regex.IsMatch(text, "^[A-Z0-9/+=]*$" , RegexOptions.IgnoreCase))                  {                      return "包含不正确的BASE64编码" ;                  }                  string Base64Code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" ;                  int page = text.Length / 4;                  ArrayList outMessage = new ArrayList(page * 3);                  char [] message = text.ToCharArray();                  for ( int i = 0; i < page; i++)                  {                      byte [] instr = new byte [4];                      instr[0] = ( byte )Base64Code.IndexOf(message[i * 4]);                      instr[1] = ( byte )Base64Code.IndexOf(message[i * 4 + 1]);                      instr[2] = ( byte )Base64Code.IndexOf(message[i * 4 + 2]);                      instr[3] = ( byte )Base64Code.IndexOf(message[i * 4 + 3]);                      byte [] outstr = new byte [3];                      outstr[0] = ( byte )((instr[0] << 2) ^ ((instr[1] & 0x30) >> 4));                      if (instr[2] != 64)                      {                          outstr[1] = ( byte )((instr[1] << 4) ^ ((instr[2] & 0x3c) >> 2));                      }                      else                      {                          outstr[2] = 0;                      }                      if (instr[3] != 64)                      {                          outstr[2] = ( byte )((instr[2] << 6) ^ instr[3]);                      }                      else                      {                          outstr[2] = 0;                      }                      outMessage.Add(outstr[0]);                      if (outstr[1] != 0)                          outMessage.Add(outstr[1]);                      if (outstr[2] != 0)                          outMessage.Add(outstr[2]);                  }                  byte [] outbyte = ( byte [])outMessage.ToArray(Type.GetType( "System.Byte" ));                  return Encoding.Default.GetString(outbyte);              }              catch (Exception ex)              {                  throw ex;              }          }          #endregion      } }

转载于:.html

本文标签: net加密解密