zoukankan      html  css  js  c++  java
  • 再谈Cookies欺骗

    上一篇关于cookies欺骗的随笔中,提到的解决方案是把密码MD5加密之后存入cookies中,确实这种方法实现了效果,不过把密码留在客户端等待着去被破解不是一个合适的方法,在此也感谢 @老牛吃肉 以及各位小伙伴们的热烈讨论。在这里改写了一下方案,记录一下。

    废话不多说直接上代码:

    先写一个DES加密类,可以直接拿走用,所以虽然是写DEMO也给单独拿出来了。

     1 using System;
     2 using System.Data;
     3 using System.Web.Security;
     4 using System.Security.Cryptography;
     5 using System.Text;
     6 using System.IO;
     7 
     8 /// <summary>
     9 /// DES 的摘要说明
    10 /// </summary>
    11 public class DES
    12 {
    13     public DES()
    14     {}
    15 
    16     /// <summary>
    17     /// 加密
    18     /// </summary>
    19     /// <param name="Text"></param>
    20     /// <param name="sKey"></param>
    21     /// <returns></returns>
    22     public static string Encrypt(string Text, string sKey)
    23     {
    24         DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
    25         byte[] bytes = Encoding.Default.GetBytes(Text);
    26         provider.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
    27         provider.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
    28         MemoryStream stream = new MemoryStream();
    29         CryptoStream stream2 = new CryptoStream(stream, provider.CreateEncryptor(), CryptoStreamMode.Write);
    30         stream2.Write(bytes, 0, bytes.Length);
    31         stream2.FlushFinalBlock();
    32         StringBuilder builder = new StringBuilder();
    33         foreach (byte num in stream.ToArray())
    34         {
    35             builder.AppendFormat("{0:X2}", num);
    36         }
    37         return builder.ToString();
    38     }
    39 
    40 
    41     /// <summary>
    42     /// 以默认密钥加密
    43     /// </summary>
    44     /// <param name="Text"></param>
    45     /// <returns></returns>
    46     public static string Encrypt(string Text)
    47     {
    48         return Encrypt(Text, "http://www.cnblogs.com/webconfig");
    49     }
    50 
    51 
    52     /// <summary>
    53     /// 解密
    54     /// </summary>
    55     /// <param name="Text"></param>
    56     /// <param name="sKey"></param>
    57     /// <returns></returns>
    58     public static string Decrypt(string Text, string sKey)
    59     {
    60         DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
    61         int num = Text.Length / 2;
    62         byte[] buffer = new byte[num];
    63         for (int i = 0; i < num; i++)
    64         {
    65             int num3 = Convert.ToInt32(Text.Substring(i * 2, 2), 0x10);
    66             buffer[i] = (byte)num3;
    67         }
    68         provider.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
    69         provider.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
    70         MemoryStream stream = new MemoryStream();
    71         CryptoStream stream2 = new CryptoStream(stream, provider.CreateDecryptor(), CryptoStreamMode.Write);
    72         stream2.Write(buffer, 0, buffer.Length);
    73         stream2.FlushFinalBlock();
    74         return Encoding.Default.GetString(stream.ToArray());
    75     }
    76 
    77 
    78 
    79     /// <summary>
    80     /// 以默认密钥解密
    81     /// </summary>
    82     /// <param name="Text"></param>
    83     /// <returns></returns>
    84     public static string Decrypt(string Text)
    85     {
    86         return Decrypt(Text, "http://www.cnblogs.com/webconfig");
    87     }
    88 }

    Login

     1     protected void Page_Load(object sender, EventArgs e)
     2     {
     3         //为了方便演示,每次加载登录页面“归零”
     4         Response.Cookies["uid"].Value = "0";
     5     }
     6     protected void Button1_Click(object sender, EventArgs e)
     7     {
     8         //验证步骤略过,假设用户通过验证并且得到如下信息:
     9 
    10         int uid = 1; //用户唯一ID
    11         string username = "admin"; //用户名
    12         string userpwd = "123456"; //用户密码
    13 
    14         string uidstr = DES.Encrypt(uid.ToString());
    15 
    16         //接下来要保存用户登录状态
    17         Response.Cookies["uid"].Value = uidstr;
    18 
    19         //跳转到登录后的页面
    20         Response.Redirect("Main.aspx");
    21 
    22     }
    23     protected void Button2_Click(object sender, EventArgs e)
    24     {
    25         //未经验证直接进入Main.aspx
    26         Response.Redirect("Main.aspx");
    27     }


    Main

     1     protected void Page_Load(object sender, EventArgs e)
     2     {
     3         CheckLogin();
     4     }
     5 
     6 
     7     private void CheckLogin()
     8     {
     9 
    10         if (Request.Cookies["uid"] != null && Request.Cookies["uid"].Value != "") //判断cookies是否存在
    11         {
    12             int uid = 0;
    13             try
    14             {
    15                 uid = int.Parse(DES.Decrypt(Request.Cookies["uid"].Value));
    16             }
    17             catch //捕获 cookies参数错误:非正确的 DES加密格式 或者解密后类型无法转换为int
    18             {
    19                 Response.Write("您尚未登陆,<a href='login.aspx'>点此登录</a>");
    20                 return;
    21             }
    22 
    23             if (GetUserInfo(uid, "") != "") //判断UID 是否存在
    24             {
    25                 Response.Write(GetUserInfo(uid, "username") + "已登录");
    26             }
    27             else
    28             {
    29                 Response.Write("您尚未登陆,<a href='login.aspx'>点此登录</a>");
    30             }
    31         }
    32         else
    33         {
    34             Response.Write("您尚未登陆,<a href='login.aspx'>点此登录</a>");
    35         }
    36     }
    37 
    38 
    39     /// <summary>
    40     /// 模拟一个获取用户信息的方法
    41     /// 然而实际操作中需要通过ID查询数据库来获取用户信息
    42     /// 这里为了方便演示就直接return固定的值了
    43     /// </summary>
    44     /// <param name="uid"></param>
    45     /// <param name="key"></param>
    46     /// <returns></returns>
    47     private string GetUserInfo(int uid, string key)
    48     {
    49         if (uid == 1) //这里只设置uid为1的用户,其他的UID的用户不存在
    50         {
    51             switch (key)
    52             {
    53                 case "username": return "admin";
    54                 case "password": return "123456";
    55                 default: return "null";
    56             }
    57         }
    58         else
    59         {
    60             return "";
    61         }
    62     }


    最后来看测试效果:

    UID是加密过的字符串,如果用户想用通过修改cookies的方法,那么他需要满足一下两个条件

    1,猜中其他用户的UID

    2,猜中网站DES加密的密钥

    最后通过UID和密钥进行加密,把cookies修改为加密后的字符串

    不过,第一条可能可以猜中,但是第二条,一般情况下密钥管理的好的话是不会有太大问题的。

    本例DEMO:http://files.cnblogs.com/webconfig/Cookies%E6%AC%BA%E9%AA%972.rar

    本文出自 低调码农的笔记簿http://www.cnblogs.com/webconfig/p/3624831.html 转载请注明出处,如有谬误不当之处,欢迎指正拍砖,不胜感谢!!

  • 相关阅读:
    [原]Jenkins(七)---jenkins项目编译测试发布由maven构建的web项目
    [原]jenkins(六)---jenkins远程部署脚本
    [原]jenkins(五)---jenkins添加项目
    [原]Jenkins(四)---Jenkins添加密钥对
    [原]Jenkins(三)---Jenkins初始配置和插件配置
    [原]Jenkins(二)---jenkins之Git+maven+jdk+tomcat
    mysql给root开启远程访问权限
    [原]git的使用(六)---远程仓库
    [原]git的使用(五)---删除文件
    [原]git的使用(四)---撤销修改
  • 原文地址:https://www.cnblogs.com/webconfig/p/3624831.html
Copyright © 2011-2022 走看看