淺談貝貝遊戲資料加密解密方式
//加密資料
WORD CTCPSocket::EncryptBuffer(BYTE pcbDataBuffer[], WORD wDataSize, WORD wBufferSize)
{
//效驗引數
ASSERT(wDataSize>=sizeof(TCP_Head));
ASSERT(wBufferSize>=(wDataSize+2*sizeof(DWORD)));
ASSERT(wDataSize<=(sizeof(TCP_Head)+SOCKET_TCP_PACKET));
//調整長度
WORD wEncryptSize=wDataSize-sizeof(TCP_Command),wSnapCount=0;
if ((wEncryptSize%sizeof(DWORD))!=0)
{
wSnapCount=sizeof(DWORD)-wEncryptSize%sizeof(DWORD);
memset(pcbDataBuffer+sizeof(TCP_Info)+wEncryptSize,0,wSnapCount);
}
//效驗碼與位元組對映
BYTE cbCheckCode=0;
for (WORD i=sizeof(TCP_Info);i<wDataSize;i++)
{
cbCheckCode+=pcbDataBuffer[i];
pcbDataBuffer[i]=MapSendByte(pcbDataBuffer[i]);
}
//填寫資訊頭
TCP_Head * pHead=(TCP_Head *)pcbDataBuffer;
pHead->TCPInfo.cbCheckCode=~cbCheckCode+1;
pHead->TCPInfo.wPacketSize=wDataSize;
pHead->TCPInfo.cbDataKind=SOCKET_VER;
//建立金鑰
DWORD dwXorKey=m_dwSendXorKey;
if (m_dwSendPacketCount==0)
{
//生成第一次隨機種子
GUID Guid;
CoCreateGuid(&Guid);
dwXorKey=GetTickCount()*GetTickCount();
dwXorKey^=Guid.Data1;
dwXorKey^=Guid.Data2;
dwXorKey^=Guid.Data3;
dwXorKey^=*((DWORD *)Guid.Data4);
//隨機對映種子
dwXorKey=SeedRandMap((WORD)dwXorKey);
dwXorKey|=((DWORD)SeedRandMap((WORD)(dwXorKey>>16)))<<16;
dwXorKey^=g_dwPacketKey;
m_dwSendXorKey=dwXorKey;
m_dwRecvXorKey=dwXorKey;
}
//加密資料
WORD * pwSeed=(WORD *)(pcbDataBuffer+sizeof(TCP_Info));
DWORD * pdwXor=(DWORD *)(pcbDataBuffer+sizeof(TCP_Info));
WORD wEncrypCount=(wEncryptSize+wSnapCount)/sizeof(DWORD);
for (i=0;i<wEncrypCount;i++)
{
*pdwXor++^=dwXorKey;
dwXorKey=SeedRandMap(*pwSeed++);
dwXorKey|=((DWORD)SeedRandMap(*pwSeed++))<<16;
dwXorKey^=g_dwPacketKey;
}
//插入金鑰
if (m_dwSendPacketCount==0)
{
MoveMemory(pcbDataBuffer+sizeof(TCP_Head)+sizeof(DWORD),pcbDataBuffer+sizeof(TCP_Head),wDataSize);
*((DWORD *)(pcbDataBuffer+sizeof(TCP_Head)))=m_dwSendXorKey;
pHead->TCPInfo.wPacketSize+=sizeof(DWORD);
wDataSize+=sizeof(DWORD);
}
//設定變數
m_dwSendPacketCount++;
m_dwSendXorKey=dwXorKey;
return wDataSize;
}
<pre name="code" class="cpp">//解密資料
WORD CTCPSocket::CrevasseBuffer(BYTE pcbDataBuffer[], WORD wDataSize)
{
//效驗引數
ASSERT(m_dwSendPacketCount>0);
ASSERT(wDataSize>=sizeof(TCP_Head));
ASSERT(((TCP_Head *)pcbDataBuffer)->TCPInfo.wPacketSize==wDataSize);
//調整長度
WORD wSnapCount=0;
if ((wDataSize%sizeof(DWORD))!=0)
{
wSnapCount=sizeof(DWORD)-wDataSize%sizeof(DWORD);
memset(pcbDataBuffer+wDataSize,0,wSnapCount);
}
//解密資料
DWORD dwXorKey=m_dwRecvXorKey;
DWORD * pdwXor=(DWORD *)(pcbDataBuffer+sizeof(TCP_Info));
WORD * pwSeed=(WORD *)(pcbDataBuffer+sizeof(TCP_Info));
WORD wEncrypCount=(wDataSize+wSnapCount-sizeof(TCP_Info))/4;
for (WORD i=0;i<wEncrypCount;i++)
{
if ((i==(wEncrypCount-1))&&(wSnapCount>0))
{
BYTE * pcbKey=((BYTE *)&m_dwRecvXorKey)+sizeof(DWORD)-wSnapCount;
CopyMemory(pcbDataBuffer+wDataSize,pcbKey,wSnapCount);
}
dwXorKey=SeedRandMap(*pwSeed++);
dwXorKey|=((DWORD)SeedRandMap(*pwSeed++))<<16;
dwXorKey^=g_dwPacketKey;
*pdwXor++^=m_dwRecvXorKey;
m_dwRecvXorKey=dwXorKey;
}
//效驗碼與位元組對映
TCP_Head * pHead=(TCP_Head *)pcbDataBuffer;
BYTE cbCheckCode=pHead->TCPInfo.cbCheckCode;
for (int i=sizeof(TCP_Info);i<wDataSize;i++)
{
pcbDataBuffer[i]=MapRecvByte(pcbDataBuffer[i]);
cbCheckCode+=pcbDataBuffer[i];
}
if (cbCheckCode!=0) throw TEXT("資料包效驗碼錯誤");
return wDataSize;
}
上面程式碼是從網狐的原始碼裡面摘選出來的 他們預設的加密和解密祕鑰是:0X12345678 這種加密方式和解密方式很簡單安全性呢說呢如果資料被攔截 比如通過裝置攔截資料是可以再中間加密解密出來的,就是說如果有人想從資料方面 至少是可以把資料給攔截下面並且知道里面具體是什麼資料,在安全性方面並不能夠達到特別安全‘
然而對於貝貝遊戲,貝貝遊戲原始碼應該是從之前998遊戲手上購買的,他們的加密形式比較複雜,因為我手上並沒有貝貝遊戲的原始碼 我只能通過逆向簡單說一下他們的加密方式
加密方式主要有AES加密
我找了一個AES 加密解密的DEMO 截圖
<pre name="code" class="cpp">"
還有一種是RSA加密
(RSA是目前最有影響力的公鑰加密演算法,它能夠抵抗到目前為止已知的絕大多數密碼攻擊,已被ISO推薦為公鑰資料加密標準。)
可見他們加密的嚴密程度是非常嚴的,可以斷定的說即使你在中途把資料攔截下來你如果沒有私鑰你也沒法破解出祕鑰的,因為對於RSA私鑰只會儲存到遊戲伺服器端,其他地方均不會出現。
下面是百度RSA加密解密處理流程
大概理論知識說得差不多了,接下來我們主要給大家理清一下這個棋牌遊戲他是如何和伺服器通訊的
大概步驟是這樣的
1:第一步 客服端和伺服器建立起TCP 連結,3次握手後傳送資料給伺服器端,第一個傳送的資料是AES的加密金鑰,這個金鑰是隨機生成的,以後在這個SOCK連線中一直是用這個祕鑰進行通訊的,客服端先隨機生成一個祕鑰然後通過用RSA的方法+RSA公鑰加密 把加密資料傳送到伺服器端
伺服器端通過RSA私鑰把傳送過來的資料解密出來,解密出來的即是AES的金鑰,這個金鑰是既作為在這個SOCK斷開之前一直用的。到目前為止RSA加密就到此為止了,之後RSA即派不上用場了,所以RSA演算法只是作為一個加密金鑰的作用,那有人會問這樣安全嗎?說實話正是因為用RSA演算法才讓整個接下來的資料變得安全,因為一般的加密演算法都是一個金鑰,客服端要加密這個金鑰肯定會在客服端出現,然後RSA機制是公鑰在客服端,然後私鑰只在服務端,即保證了在傳送祕鑰的過程中即使資料被攔截人家要解密不出來金鑰,還有人會問既然這麼安全為什麼不一致都用RSA呢,其實很簡單RSA加密演算法安全其實是建立在他複雜上面,既然複雜他的處理流程是很慢的,加密解密速度是很慢的,尤其是作為遊戲如果光一個資料加密解密就需要很長時間,那麼遊戲之前通訊如此頻繁遊戲肯定會感覺很卡,因為資料不能及時被處理。所以他只是在建立SOCK的時候呼叫一下這個演算法
2:第二步 既然客服端隨機生成的祕鑰已經通知到伺服器端了,那麼他們之後的資料都是用AES 這種演算法速度很快,而且在不知道金鑰的情況下也是很安全的,而這個金鑰是
隨機的,所以你說安全嗎
貝貝遊戲AES加密演算法呼叫處
貝貝遊戲AES解密演算法呼叫處
上面截圖是在貝貝遊戲中AES加密解密的地方。
大概貝貝的資料加密解密就是通過上面2個步驟,所以說貝貝遊戲在資料安全性方面還是很不錯的,至少個人感覺很嚴密。
上面大致闡述了一下貝貝遊戲的在通訊方面的方式方法,裡面可能有很多因為自己能力有限有錯誤的地方或者有限的地方請自動忽略,個人微信feilongqp 歡迎加我
相關文章
- 淺談如何學習加密與解密技術加密解密
- java使用DES加密方式,實現對資料的加密解密Java加密解密
- Flutter 的加密和解密資料Flutter加密解密
- 資料加密方式:APM加密
- 淺談加密技術加密
- dbms_obfuscation_toolkit(資料加密解密)加密解密
- 資料的加密和解密初識加密解密
- win10加密資料夾如何解密_win10已加密的資料夾如何解密Win10加密解密
- 淺談遊戲遊戲
- java實現DES資料加密與解密Java加密解密
- 後臺對Json資料加密、解密JSON加密解密
- 在PHP中使用AES加密演算法加密資料及解密資料PHP加密演算法解密
- faust勒索病毒攻擊加密Windows系統的方式,勒索病毒解密資料恢復加密Windows解密資料恢復
- 淺談圖資料庫資料庫
- 圖資料庫淺談資料庫
- AutoMySQLBackup加密備份解密問題淺析MySql加密解密
- 如何在Python中加密和解密資料Python加密解密
- Oracle對資料進行加密&解密處理Oracle加密解密
- 淺談CSRF攻擊方式
- 加密解密加密解密
- 小程式加密資料解密演算法java版加密解密演算法Java
- iOS中使用RSA對資料進行加密解密iOS加密解密
- 淺談資料庫事務資料庫
- 淺談資料的表格化
- 淺談 Redis 資料結構Redis資料結構
- 淺談資料分析入門
- 淺談資料庫連線資料庫
- 淺談IAT加密原理及過程加密
- 淺談資料倉儲和大資料大資料
- 淺談ddos的測試方式
- 淺談遊戲安全 (一)遊戲
- 淺談遊戲的經濟資源系統遊戲
- AES實現財務資料的加密解密儲存加密解密
- 【資料結構】淺談主席樹資料結構
- 淺談HBase的資料分佈
- 淺談醫學大資料(上)大資料
- 淺談醫學大資料(中)大資料
- 淺談資料庫備份方案資料庫