lua 與 php 通過AES數(shù)據(jù)加密進(jìn)行通訊
最近公司有款《圍住神經(jīng)貓》的微信小游戲火爆的不行!公司又決定開發(fā)一系列的神經(jīng)貓的小游戲,于是,我被拉過來了。
后來使用cocos-2dx 開發(fā)一款小游戲,客戶端用的是lua腳本,為了服務(wù)器與客戶端交互的安全性,我們決定對(duì)API接口
傳輸?shù)腏SON數(shù)據(jù)進(jìn)行加密、解密。一般情況就是客戶端加密,服務(wù)器段進(jìn)行解密:
lua客戶端使用的是一個(gè)純lua寫的庫(kù):aeslua,下載地址:http://luaforge.net/projects/aeslua/
但是該庫(kù)是有問題的:用該庫(kù)加密解密是沒有問題的,但是跟PHP通訊就存在問題了,因?yàn)樵搸?kù)加密后base64之后的
字符串PHP是無法解密的!為了這個(gè)問題,我查閱了好多資料,終于找到某個(gè)國(guó)外大神的解決辦法:
http://chainans.blogspot.com/2012/09/working-with-lua-encryption.html(可能有些同學(xué)無法FQ,故把原文貼出來如下:)
Working with Lua encryption
Recently working with Corona SDK, I start to need some standard encryption/decryption algorithm in Lua. To start with, actually, it has rather small number of developers comparing to the Objective-C which I have been working with. Meaning that there are fewer 3rd party librarys you can rely upon. Luckily, I found one called AESLua which has some code to start. From there, my objective is to make a way to securely passing data between my client and server. (php on server-side) In fact, from what I'd read, my method is not very secure but it is better than nothing. Just for my reference, here are the list of issues along the way
Edited: Tested with iPhone 4... Input cipher text of 1280 characters. Take around 25 seconds. Unacceptable speed for general uses.
1) It requires Lua 5.2 feature which does not seem to be in Corona
Solution: Download?LuaBit v0.4 and integrate it... You will need to make a mapping to allow API call to the proper place
2) Next you need to get Base64 library -- grab it here?https://gist.github.com/2563975 -- It initially made to allow passing it over the URL (using '-' and '_' instead of '+' and '/') So, I change them to the latter one.
3) For AESLua, by default, it uses AES-128, CBC, some kind of random padding
http://www.unsw.adfa.edu.au/~lpb/src/AEScalc/AEScalc.html
http://www.tools4noobs.com/online_tools/decrypt/
Here are the things to do
3.1) In pwInKey function, comment the line out
?
password = ciphermode.encryptString(pwBytes, password, ciphermode.encryptCBC);
3.2) In util.padByteString function, change it to
? ? local paddingLength = math.ceil(#data/16)*16 - #data;
? ? local padding = "";
? ? local paddingValue = string.char ( paddingLength ) ?-- PKCS7 padding
? ? for i=1,paddingLength do
padding = padding .. paddingValue;-- PKCS7 padding
? ? end?
? ? return data .. padding;
4) Set up web server for testing, you will need php /?mcrypt mod to test.
5) Creating a php for testing... here is a code
Now, my plain text below is "1234567890123456ss@#%de".
$data = 'dXzNDNxckOrb7uz2ON0AAJp4BXgkYewblTNWBSAQSEw=';
$key128 = '1234567890123456';
$iv = ?'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0';
echo mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key128, base64_decode($data), MCRYPT_MODE_CBC, $iv)
?>
That's it. The encryption backward to client machine should be a piece of cake.?=)
*** By using these library, the user should be aware of the fact that Lua's performance is still far from native code. You may not want to use this algorithm to encrypt a large volume of data.
按照他的辦法,一切都OK了。但是有以下幾點(diǎn)需要說明以下:(本人摸索的)
1.利用CBC模式加密的字符串的key必須是16位,否則PHP無法解密!
2.明文字符串的必須把key作為前綴加進(jìn)去
3.上面文章中沒有把unpack函數(shù)寫出來,本人查閱了一些資料,補(bǔ)充了,否則aeslua無法正常解密了!
util.lua中的下面這個(gè)函數(shù)改為如下:
function public.unpadByteString(data)
? ? local padLength = tonum((string.byte(data, #data)));
? ? return string.sub(data,1, #data-padLength) ? --unpack
end