用ILSpy查看Session.SessionID的生成算法
2018-06-22 07:34:20来源:未知 阅读 ()
缘由
asp.net Session在InProc模式下,容易丢失,经常需要重新登录,且不支持分布式共享。
所以在研究Redis实现原生的Session,本来想用GUID作为key存入cookie,又在想能不能实现跟Session一样的id
实现
ILSpy 是一个开源的.NET反编译工具,简洁强大易用是它的特征。在绝大多数情况下,它都能很好的完成你对未知程序集内部代码的探索。
ILSpy 下载地址:点击下载
在VS中可以得知SessionID是System.Web.SessionState命名空间的HttpSessionState类下的属性。
在ILSpy中搜索HttpSessionState,找到Session属性,是IHttpSessionState接口对象创建的。
查看HttpSessionState的构造函数,原来IHttpSessionState是从构造函数传过来的。
本来是想通过搜索构造函数找到是哪传过来这个对象的,只是ILSpy只提供类型,成员,常量的搜索
折腾了好久,终于找到IHttpSessionState的接口实现类HttpSessionStateContainer
DelayedGetSessionId方法
CreateSessionId方法
在追踪CreateSessionID方法,是个接口中定义的方法
搜索CreateSessionID方法,找到具体的现实
最后找到Create方法的所在类
测试
具体的代码:
internal static class SessionId { internal const int NUM_CHARS_IN_ENCODING = 32; internal const int ENCODING_BITS_PER_CHAR = 5; internal const int ID_LENGTH_BITS = 120; internal const int ID_LENGTH_BYTES = 15; internal const int ID_LENGTH_CHARS = 24; private static char[] s_encoding; private static bool[] s_legalchars; internal static bool IsLegit(string s) { if (s == null || s.Length != 24) { return false; } bool result; try { int num = 24; while (--num >= 0) { char c = s[num]; if (!SessionId.s_legalchars[(int)c]) { result = false; return result; } } result = true; } catch (IndexOutOfRangeException) { result = false; } return result; } internal static string Create(ref RandomNumberGenerator randgen) { if (randgen == null) { randgen = new RNGCryptoServiceProvider(); } byte[] array = new byte[15]; randgen.GetBytes(array); return SessionId.Encode(array); } static SessionId() { SessionId.s_encoding = 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', '0', '1', '2', '3', '4', '5' }; SessionId.s_legalchars = new bool[128]; for (int i = SessionId.s_encoding.Length - 1; i >= 0; i--) { char c = SessionId.s_encoding[i]; SessionId.s_legalchars[(int)c] = true; } } private static string Encode(byte[] buffer) { char[] array = new char[24]; int num = 0; for (int i = 0; i < 15; i += 5) { int num2 = (int)buffer[i] | (int)buffer[i + 1] << 8 | (int)buffer[i + 2] << 16 | (int)buffer[i + 3] << 24; int num3 = num2 & 31; array[num++] = SessionId.s_encoding[num3]; num3 = (num2 >> 5 & 31); array[num++] = SessionId.s_encoding[num3]; num3 = (num2 >> 10 & 31); array[num++] = SessionId.s_encoding[num3]; num3 = (num2 >> 15 & 31); array[num++] = SessionId.s_encoding[num3]; num3 = (num2 >> 20 & 31); array[num++] = SessionId.s_encoding[num3]; num3 = (num2 >> 25 & 31); array[num++] = SessionId.s_encoding[num3]; num2 = ((num2 >> 30 & 3) | (int)buffer[i + 4] << 2); num3 = (num2 & 31); array[num++] = SessionId.s_encoding[num3]; num3 = (num2 >> 5 & 31); array[num++] = SessionId.s_encoding[num3]; } return new string(array); } }
调用:
public partial class Contact : Page { protected void Page_Load(object sender, EventArgs e) { string SessionId = CreateSessionID(Context); Response.Write(SessionId+"<br/>");
Response.Write(Session.SessionID); Response.End(); } private RandomNumberGenerator _randgen; public virtual string CreateSessionID(HttpContext context) { return SessionId.Create(ref this._randgen); } }
效果截图:
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:SSL通信-忽略证书认证错误
- 【转载】 使用宝塔Linux面板功能查看服务器内存使用情况 2019-07-23
- 【转载】如何查看sqlserver客户端的版本号信息 2019-07-23
- 如何创建一个用弹出窗口来查看详细信息的超链接列 2019-06-16
- 分析器错误(在浏览器中查看.aspx) 2018-06-22
- 查看C#的dll所依赖.Net版本 2018-06-22
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash