用SRP6协议实现游戏登录流程

 用SRP6协议实现游戏登录流程

 

       大家都知道,在网络游戏开发中,客户端登录是服务器端程序设计最重要的一环,在这个环节,要考虑的最主要的是玩家账号的安全问题.在当下网络环境中,黑客,网络监听软件横行,因此我们必须要有一种安全机制来确保用户的帐号不被他人盗取.身份验证方法有很多种,在我们公司的游戏开发中,采用的是SRP6协议.

 

      SRP协议是由斯坦福大学计算机科学系的Thomas wu等开发的,英文全称是Security Remote Password(安全远程密码),经过严密的数学论证,SRP6被证明是一种非常安全的算法,我们可以在这里获取到SRP的协议的官方文档http://srp.stanford.edu/ndss.html.在当下流行的网络游戏中,魔兽世界采用的就是SRP协议.

SRP协议的机制和验证流程如下:

(1)协议中用到的符号表示的含义如下:

N     N = 2q + 1 , q 是一个素数,下面所有的取模运算都和这个 N 有关

g     一个 N 的模数,应该是 2 个巨大的素数乘得来

k     k = H(N,G) 在 SRP6 中 k = 3

s      User’s Salt

I      用户名

p     明文密码

H()  单向 hash 函数

^      求幂运算

u     随机数

a,b   保密的临时数字

A,B  公开的临时数字

x     私有密匙(从 p 和 s 计算得来)

v     密码验证数字

其中 x  =  H(s,p) 和 v = g ^ x , s 是随机选择的, v 用来将来验证密码。

(2)验证流程:

         客户端                                                                    服务器

                                           帐号--------->             从数据库中取出帐号对应的密码P,随机生成N,g,s,利用公

                                                                           式v=g^x生成密码验证数字v

     收到s后计算x=H(s,P)       <-------------N,g,s

    随机生成a,计算A=g^a        A------------>            收到A后,随机生成b,计算B=v + g^b,生成u=H(A+B)

          计算u=H(A+B)            <------------B             发送B给客户端

    S = (B - g^x)^(a + ux)                                          S = (A · v^u)^b

          K = H(S)                                                              K = H(S)

     M[1] = H(A, B, K)           M[1]-------->               收到M[1]之后,验证与服务器计算出的M[1]是否相同

                                                                             相同则计算M[2],不同则发送密码错误给客户端

                                          <----------M[2]                        M[2] = H(A, M[1], K)

     验证M[2]

 

以上所有的运算都是以N求余,我在上边省略了,但是在具体实现时一定不要忘了.

SRP6的原理基本上就是上边所说的.

 

具体SRP6的C++实现,我会在下边给出源码.

 

SRP6在实际中的应用.

 

(1)定义消息码:

 

 enum{

          LOGIN_VALID = 0;

          LOGIN_REQUEST;

          LOGIN_SEND_ACCOUNT;

          LOGIN_SEND_A;

          LOGIN_SEND_M1;

 

         LOGIN_SEND_NGS;

         LOGIN_SEND_B;

         LOGIN_SEND_M2;

};

 

(2)定义在网络中发送的消息包结构体:

   struct    PKT_BASE

   {

         unsigned char  ucMsgCode;

         PKT_BASE( void ){ ucMsgCode = LOGIN_VALID; }

   };

   struct    PKT_C2L_LOGIN_REQ

   {

         PKT_C2L_LOGIN_REQ(){ ucMsgCode = LOGIN_REQUEST; }

   };

 

   struct  PKT_C2L_LOGIN_A

   {

         unsigned char  ucA[32];

         PKT_C2L_LOGIN_A( unsigned char A[32] )

         {

               ucMsgCode = LOGIN_SEND_A;

               memset( ucA,0,32 );

               memcpy( ucA,A,32 );

         }

   };

 

   struct   PKT_C2L_LOGIN_ACCOUNT

   {

          unsigned char ucAccount[MAX_ACCOUNT_LENGTH];

          PKT_C2L_LOGIN_ACCOUNT( unsigned char  account[] )

          {

                ucMsgCode = LOGIN_SEND_ACCOUNT;

                memset( ucAccount,0,MAX_ACCOUNT_LENGTH );

                memcpy( ucAccount,account,MAX_ACCOUNT_LENGTH );

          }

   }

    ..................................................其它的定义大体如此,就不再多写了......................................................

(3) 消息处理

 

     void Client_Recv_Data( void * pData,  unsigned int len )

     {

            PKT_BASE *pPacket = ( PKT_BASE *)pData;

            switch( pPacket->ucMsgCode )

            {

                  case   LOGIN_SEND_NGS:

                         ProcessNGS( pData,len );

                         break;

                  case   LOGIN_SEND_B:

                         ProcessB( pData,len );

                         break;

                  case   LOGIN_SEND_M2:

                         ProcessM2( pData,len );

                         break;

                  default:

                         std::cout<<"Message Error."<

            }

     }

     //服务器端的消息处理函数同客户端基本相同,就不写了.

具体SRP6模块的实现,如果您有需要可以留下邮箱,我会发给你.希望此文对大家有所帮助.

你可能感兴趣的:(用SRP6协议实现游戏登录流程)