一个登陆认证系统
最近在忙代理项目 狂刃 的事情。
因为这个项目,我们提前建立了平台开发团队。但许多东西开始的都很仓促,比如需要对接用户登陆认证系统。
虽然已经有很多成熟的认证协议,比如最有名的 kerberos 。但这次时间紧迫,我就临时设计了一个简单协议。
因为不是 web 应用接入,所以我不想直接使用 https 来提交用户名和密码,而基于 http 协议,在不安全信道上建立了一个自定义协议来应付一下。这种临时设计的协议当然不会很缜密,但也基本够用。
这样,合作方的客户端可以较容易实现相应模块。
在整个业务中,有三个实体:
C 玩家客户端 G 游戏服务器 E 我们的认证平台
登陆流程是这样的:
G 发现有 C 企图登陆时,生成一个一次性的 salt (如果直接用时间的话,可选对称加密),然后发送给 C
2, C 收到 salt ,利用自己的用户密码,对 salt 加密并签名。加密可以使用标准的 DES 算法,签名可以用标准的 MD5 算法。具体方法是:讲用户密码先 md5 hash 一次,得到一个串。取串的前一半做 DES 加密算法的 key 加密 salt ;然后把结果连接上密码 hash 串的后半部分,一起做一次 MD5 。密文和签名连接在一起,最终会得到一个加过签名的密文 secret 。
C 将第 2 步生成的 secret 连同自己的登陆名,以及需要登陆的游戏名发送给 E 。
E 收到 secret 后,从登陆名查询到用户信息,用保存在 E 上的密码做反向操作,验证签名是否正确。若正确则解出 salt 。失败则发送错误信息给 C ,登陆流程结束。
E 利用解开的 salt ,附加上用户 id 。利用游戏名查询到事先和 G 约定的游戏服务器密码,做同样流程的加密签名处理,发送回 C 。
C 转发认证密文回给 G 。G 用约定要的服务器密码,校验签名并解密,核对 salt 是否是在步骤 1 里发送出去的 salt ,确认用户的合法性。
整个流程,G 和 E 不必保持通讯,只需要事先约定要密码。这可视做一个简化版的 kobas 协议,其中有一些安全隐患这里不一一指出。目前暂且可用。日后再来完善。
G 和 E 不保持通讯有一个好处:G 不需要对 C 保持连接状态,而只需要最终检查一下 C 发过来的认证包就可以知道认证是否通过。
设计完毕后,我用 C 实现了基本的校验认证函数。老马同学整合到他用的 web server 中,完成了认证服务器。并做了压力测试,结果还不错。
可惜合作方是用 Windows 做开发的,不方便联调。他们在开发期不希望依赖我们的用户系统,而我们的平台系统即使给他们,在 windows 下短期也较难配置起来。
我一拍脑袋,决定帮合作方现写一个认证用 web server 在 windows 下跑。对于我来说,最称手的某过于 lua 了。利用现成的 lua socket 模块,整个认证服务器只需要不到 100 行代码 。把用户名密码直接配置在 lua 源代码中,放到一个 table 中即可,数据库都不需要。反正是调试嘛。
一开始图简单,直接 bind/listen 了 web 端口,然后没 accept 一个认证请求,就处理一个。用阻塞方式工作。我觉得也就是调试一下流程,调通了后就可以用老马做好的正式认证服务器了。
可写完之后,手又痒了。感觉不支持并发很看不过眼,赶紧重写了。
幸亏这次重写,让事后扛住了一次压力。
昨天,合作方花前请了一个公会 600 人帮忙做了一次压力测试。这次测试他们认为是自己的事情,就没有通知我们。结果因为要用他们自己的用户系统(直接对公会放号),就没有联系老马,而是用了我那个拍脑袋临时写的测试用认证服务器。
还好做了并发处理,没在这个问题上翻船。不过昨天还是出了点小事故,在晚饭间接了好几个电话才搞定。
由于一开始考虑到是测试用,我把服务器 bind 地址默认配置成了 127.0.0.1 。结果合作方直接改成了服务器的配置 ip 。然后许多玩家认证不过,客户端编写的时候又没有足够的提示信息。搞了老半天才清楚,服务器配有电信和网通双线,所以是有双 IP 的。最后配置改为 0.0.0.0 搞定了这个问题。
建议继续学习:
- GINA 与 pGINA――实现自定义的 Windows 用户身份认证 (阅读:4086)
- Apache用户认证方法汇总 (阅读:2626)
- 探索MySQL源代码-客户端连接过程和用户认证体系 (阅读:2323)
- 通过中间件来实现应用的认证 (阅读:1605)
- 使用审计功能记录错误密码登陆信息 (阅读:1342)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:云风的 BLOG 来源: 云风的 BLOG
- 标签: 登陆 认证
- 发布时间:2012-12-08 23:00:21
- [52] IOS安全–浅谈关于IOS加固的几种方法
- [51] android 开发入门
- [50] 如何拿下简短的域名
- [49] Oracle MTS模式下 进程地址与会话信
- [48] 图书馆的世界纪录
- [47] 【社会化设计】自我(self)部分――欢迎区
- [46] Go Reflect 性能
- [43] 读书笔记-壹百度:百度十年千倍的29条法则
- [37] 视觉调整-设计师 vs. 逻辑
- [35] 程序员技术练级攻略