zoukankan      html  css  js  c++  java
  • 游戏协议加密及身份验证

    时间如白驹过隙,一眨眼就过去了,本打算在2月份发这篇的,结果一直误以为2月有31日……

    这一块之前一直感兴趣,终于在2月份争取到机会去做这一块的工作。前辈给我留下了一个鉴权的框架:

    1. 客户端连接服务器
    2. 服务器将随机数发给客户端
    3. 客户端用客户端私钥加密,发回到服务器
    4. 服务器端用客户端公钥解开密文,比对解开的随机数是否与原来的一致
    5. 如果一致,则客户端发送随机数到服务器,服务器用服务器端私钥加密,将密文发送到客户端;同时,产生新的随机数,用于稍后对会话进行rc4加密,并将这个随机数以客户端公钥加密,发送到客户端。
    6. 客户端用服务器端公钥解开密钥,比对随机数和自己发的是否相同,相同的话则用客户端私钥解开下一个包,取出用于rc4加密的key密文
    7. 至此,双方身份验证完成,会话先进行压缩,再通过rc4算法进行加密

    在这里,私钥充当了一个身份的象征,只要拥有私钥,就认为对方是授信客户端。可能有朋友会问,如果客户端被破解怎么办?我觉得安全专家道哥有个观点很好,“安全的本质是信任的问题。设计任何安全方案,最终都必须要有一个东西是「假设可以信任的」,只是看这个「可信任」的东西被攻击成功的概率大小。如果不这么做,则做不出任何的安全方案。”所以,考虑协议安全的时候,我们只能选择相信客户端密钥被安全的保管着。

    回头再看看这个方案,这里用到了私钥进行加密。熟悉ssh的同学应该会联想到其挑战过程,ssh服务器是用客户端公钥对随机数进行加密,再发送到客户端的。公钥加密和私钥加密的区别是,在明文相同的情况下,公钥加密出来的密文每次都不一样,而私钥加密出来的密文是每次都相同的。示例代码可以参见: https://github.com/spin6lock/rsa_encrypt_and_decrypt_in_c 密文和明文总是一一映射,容易被碰撞攻击,进而绕过加密过程。因此,私钥加密多用于身份验证,比如电子邮件的数字签名,首先用md5对邮件明文进行信息摘要,然后用私钥进行加密,公钥是公开的,保证任何看到这封邮件的人都可以进行解密,获取md5信息进行验证,确保邮件没有被纂改。

    于是,我花了一周左右的时间修改了验证流程。新的验证流程如下:

    1. 客户端连接服务器
    2. 服务器用客户端公钥加密随机数,发给客户端
    3. 客户端用客户端私钥解密,发回服务器
    4. 服务器对比随机数,不一样的话就断开连接
    5. 客户端用服务器端公钥加密随机数,发送到服务器
    6. 服务器用私钥解密,发送回客户端
    7. 客户端验证通过
    8. 服务器用客户端公钥加密rc4会话所用密钥,发送到客户端
    9. 客户端用公钥解开,接下来在rc4加密下上传

    接下来,想针对手机网络模块的工作特点进行协议优化。由于手机受限于电量,网络芯片工作时会有启动,半速,全速,半速,设备待机这个速度曲线,如果能够在应用层对包进行打包发送,能够大大提高手机的待机时间,参见这篇开发指南。协议压缩放在下一篇吧~

  • 相关阅读:
    .NET实现Excel文件的读写 未测试
    权限管理设计
    struts1中配置应用
    POJ 2139 Six Degrees of Cowvin Bacon(floyd)
    POJ 1751 Highways
    POJ 1698 Alice's Chance
    POJ 1018 Communication System
    POJ 1050 To the Max
    POJ 1002 4873279
    POJ 3084 Panic Room
  • 原文地址:https://www.cnblogs.com/Lifehacker/p/mobile_game_protocol_encrypt_and_authentication.html
Copyright © 2011-2022 走看看