- 注册时间
- 2011-8-8
- 最后登录
- 1970-1-1
该用户从未签到
|
密的,这里是具体的加密算法:
if (this._encrypted)
{
//param1是要发送的数据包
_loc_2 = 0;
while (_loc_2 < param1.length)
{
if (_loc_2 > 0)
{
SEND_KEY[_loc_2 % 8] = SEND_KEY[_loc_2 % 8] + param1[(_loc_2 - 1)] ^ _loc_2;
param1[_loc_2] = (param1[_loc_2] ^ SEND_KEY[_loc_2 % 8]) + param1[(_loc_2 - 1)];
}
else
{
param1[0] = param1[0] ^ SEND_KEY[0];
}
_loc_2 = _loc_2 + 1;
}
DDT有两个KEY,分别是SEND_KEY和RECEIVE_KEY分别用于发送数据包时加密和收到数据包时解密,解密的算法如下:
while (_loc_4 < param2)
{
if (_loc_4 > 0)
{
param3[_loc_4 % 8] = param3[_loc_4 % 8] + param1[(_loc_4 - 1)] ^ _loc_4;
_loc_5[_loc_4] = param1[_loc_4] - param1[(_loc_4 - 1)] ^ param3[_loc_4 % 8];
}
else
{
_loc_5[0] = param1[0] ^ param3[0];
}
_loc_4 = _loc_4 + 1;
}
其中param3是RECEIVE_KEY的传址引用,SEND_KEY和RECEIVE_KEY的类型都是ByteArray数组;
本地初始化的时候会发送一个KEY到服务器,而且用这个KEY同时初始化SEND_KEY和RECEIVE_KEY,这个KEY是个由8位随机数构成的数组。
var _loc_5:Array = [Math.ceil(Math.random() * 255), Math.ceil(Math.random() * 255), Math.ceil(Math.random() * 255), Math.ceil(Math.random() * 255), Math.ceil(Math.random() * 255), Math.ceil(Math.random() * 255), Math.ceil(Math.random() * 255), Math.ceil(Math.random() * 255)];
就是说每次游戏开始都会生成新的KEY。
最变态的是每次发送数据包和接收数据包后相应的SEND_KEY和RECEIVE_KEY都会改变,注意加密算法中的:SEND_KEY[_loc_2 % 8] = SEND_KEY[_loc_2 % 8] + param1[(_loc_2 - 1)] ^ _loc_2;
每次加密后SEND_KEY都会改变,RECEIVE_KEY同样如此,因为传递给解密函数的参数是个传址引用同样会改变RECEIVE_KEY的值,所以你在游戏中同样一个动作,发送的数据包却大不相同。
下面是我模拟的客户端和服务器发包和收包的过程:
Client1 计算随机KEY并发送给,当然这个KEY是加密后传送的 Server1,然后用这个KEY初始化自己的SEND_KEY和RECEIVE_KEY,服务器也用这个KEY来初始化自己的SEND_KEY和RECEIVE_KEY,为了以示区别我们分别记做CLIENT_SEND_KEY,CLENT_RECEIVE_KEY,和SERVER_SEND_KEY,SERVER_RECEIVE_KEY,这里这四个KEY应该是相等的,
然后Server发包给Client1,用SERVER_SEND_KEY来加密数据包发送给Client1,在加密的过程中SERVER_SEND_KEY改变为SERVER_SEND_KEY_1,Client收到加密的数据包,用CLIENT_RECEIVE_KEY来解密这个包,解密的过程中CLIENT_RECEIVE_KEY改变为CLIENT_RECEIVE_KEY_1,这时候SERVER_SEND_KEY_1和CLIENT_RECEIVE_KEY_1是相等地,所以下次接到服务器发包仍然能正确的解密。它们就是这样实现了KEY的同步。
客户端发包给服务器的过程也是同样地,但是这里有个问题,如果我们构造一个数据包发送给服务端为有什么效果?我认为在这之后服务器端会无法正确解密客户端的数据包,因为这个数据包是我们构造的,而游戏客户端内部并没有发送这个数据包,所以SEND_KEY没有变化,但是服务器接到这个包后,服务器端的RECEIVE_KEY会在解密过程中改变,这样下次客户端再发送数据包到服务器端时将不会正确的解密。所以我认为我们在构造数据包之后还应该更新客户端的SEND_KEY。当然我还没有找到获取客户端KEY的方法,这只是我根据程序逻辑的推测,望高手不要见笑。本文的目的是起个抛砖引玉的作用,大家有什么好的想法希望能拿出来讨论,本来flash网游解密方面的资料就少,更需要大家的合作,众人拾柴火焰高!现在主要的问题是我不知道怎样才能获取本地客户端的KEY? |
|