public static byte[] UnPack(byte[] data, out uint sess) { sess = 0; var len = data.Length; if (len == Const.HeartBeatLength) { return(new byte[] { }); } //先检查下最小长度// if (len < Const.PackageSessionLength + Const.PackageHmacLength) { DebugLogger.DebugNetworkError("Receve Data Length Error! Got " + len + " Byte, Less than Session Length plus Hmac Length"); throw new NetworkingException((int)ErrorCode.DataError); } string hmac_pkg = NetCrypter.CryptData(data, 0, len - Const.PackageHmacLength); string hmac_server = Encoding.Default.GetString(data, len - Const.PackageHmacLength, Const.PackageHmacLength); if (hmac_pkg != hmac_server) { DebugLogger.DebugNetworkError("HMAC Invalid! hmac_pkg:" + hmac_pkg + ", hmac_server: " + hmac_server); throw new NetworkingException((int)ErrorCode.DataError); } int dataLength = len - Const.PackageHmacLength - Const.PackageSessionLength; //获得SessionID// sess = NetUtil.bigEndian2UInt(data, dataLength, Const.PackageSessionLength); //拷贝获得的接收数据// var ReceiveData = new byte[dataLength]; Buffer.BlockCopy(data, 0, ReceiveData, 0, dataLength); return(ReceiveData); }
public static byte[] Pack(uint sess, string opCode, byte[] data) { int index = 0; int msglen = data.Length + Const.PackageSessionLength + Const.PackageHmacLength; byte[] header = NetUtil.ushort2bigEndian((ushort)msglen); var SendData = new byte[header.Length + msglen]; // 拷贝文件长度数据 Buffer.BlockCopy(header, 0, SendData, index, header.Length); index += header.Length; //先将数据拷贝到数据包// Buffer.BlockCopy(data, 0, SendData, index, data.Length); index += data.Length; //获得Session的Byte数据// byte[] session = NetUtil.uInt2BigEndian(sess); //拷贝Session数据// Buffer.BlockCopy(session, 0, SendData, index, session.Length); index += session.Length; //计算Hmac数据// byte[] hmac = Encoding.Default.GetBytes(NetCrypter.CryptData(SendData, header.Length, index)); //拷贝Hmac数据// Buffer.BlockCopy(hmac, 0, SendData, index, hmac.Length); return(SendData); }
public static byte[] GenHandShake(string uid, string gameServer, string subid, uint connectionIndex) { int clientReceivedSeq = 0; DebugLogger.Debug("GenHandShake uid:" + uid + " gameServer:" + gameServer + " subid:" + subid); string handshake = string.Format ( "{0}@{1}#{2}:{3}:{4}", Convert.ToBase64String(Encoding.Default.GetBytes(uid)), Convert.ToBase64String(Encoding.Default.GetBytes(gameServer)), Convert.ToBase64String(Encoding.Default.GetBytes(subid)), connectionIndex, clientReceivedSeq ); string hmac_encode64 = handshake + ":" + NetCrypter.CryptData(handshake); byte[] hmac_encode64_bits = Encoding.Default.GetBytes(hmac_encode64); return(hmac_encode64_bits); }
internal static Exception Login(string ip, int port, string account, out IProtocol p) { p = new TcpProtocol(ip, port, null); var cfg = new Dictionary <string, ProtocolCfg>() { { "SendBufferSize", new ProtocolCfg { intElement = Const.PackageMaxLength } }, { "ReceiveBufferSize", new ProtocolCfg { intElement = Const.PackageMaxLength } }, { "ReceiveTimeout", new ProtocolCfg { intElement = 3000 } } }; p.SetCfg(cfg); NodeInfo node = null; try { // 第一步建立连接 p.Connect(); //第二步,收到服务端发回的base64(8bytes random challenge)随机串,用于后序的握手验证// byte[] data = p.Read(); //第三步 生成 8bytes 随机串 client key byte[] client_key = Convert.FromBase64String(Encoding.Default.GetString(data, 0, data.Length)); data = LoginPass.GenSecretKey(data, client_key); //第四步,向服务端发送base64(DH-Exchange(client key)) 用于生成 secret 的 key p.Send(DataPack.PackLength(data)); //第五步,收到服务端发送过来的base64(DH-Exchange(server key)) 用于生成 secret 的 key data = p.Read(); //第六步,secret := DH-Secret(client key/server key)服务器和客户端都可以计算出同一个 8 字节的 secret 用来加密数据 byte[] secret = LoginPass.GenVerifySecret(data, client_key); NetCrypter.setSecret(secret); //第七步,base64(HMAC(challenge, secret))回应服务器第一步握手的挑战码,确认握手正常 data = LoginPass.GenFirstChallenge(client_key, secret); p.Send(DataPack.PackLength(data)); //第八步,DES(secret, base64(token))使用 DES 算法,以 secret 做 key 加密传输 token,token 包含帐号信息[user,sdkid] data = LoginPass.GenSecretUserToken(account, secret); p.Send(DataPack.PackLength(data)); //第九步,认证结果信息,前2个字节retcode 200 表示成功,只有成功才解析后续内容(base64(uid:subid)@base64(server)#base64(info)) data = p.Read(); node = LoginPass.ProcessLoginData(data); // 登陆完毕,关闭当前连接,准备连接node p.Close(); } catch (Exception e) { return(e); } DebugLogger.Debug("login node" + node.nodeHost + node.nodePort); // 连接节点 p = new TcpProtocol(node.nodeHost, node.nodePort, new ReConnect(UsrLogin.ConnectNode)); cfg["ReceiveTimeout"] = new ProtocolCfg { intElement = 10000 }; p.SetCfg(cfg); p.Node = node; return(ConnectNode(p.Node, p)); }