- Joined
- Jan 9, 2008
- Messages
- 818
- Reaction score
- 847
I've been wondering why MapleStory is not using its AES key to the fullest, but now I am pretty sure i found the culprit.
MapleStory has implemented an open source AES implementation,
- They removed the support of multiple keylengths (only support 32 byte keys atm). Some functions still have arguments for it, but are not used
- They removed the support for different cryptography methods (CBC, ECB, CFB), only OFB is used
- Some functions have different arguments types
The last part is what makes the bug happen. In the original AES implementation, the key initialization function (AES_EncKeySchedule and AES_DecKeySchedule) had the following arguments:
- BYTE* UserKey
- AES_ALG_INFO* AlgInfo
However, in MapleStory, they are not asking for a BYTE* UserKey, but an DWORD* UserKey!
This is probably something that they broke when they started to remove all redundant code and tried to make the original code better, because of the following:
Original RIJNDAEL_KeySchedule has the following arguments:
- BYTE* UserKey
- DWORD k_len
- DWORD* e_key
The modified variant has:
- DWORD* UserKey
- DWORD* e_key
As the code does not support key lengths anymore, the arguments changed. Its possible that they removed the code in RIJNDAEL_KeySchedule, but because the arguments didnt match, they accidentally changed the type from BYTE* to DWORD*...
The change of the argument triggers the following issue:
But the following is happening
And that, kids, show that you should carefully refactor your code. And write tests, because this wouldn't have happend if there were tests involved.
Or this is to reduce the effectiveness of AES in order to make the NSA sniff the MapleStory connections. But thats not possible with the Shanda encryption.
However, its removed from maple. Why is it removed?
And why the random UserKey now?
MapleStory has implemented an open source AES implementation,
You must be registered to see links
. However, its not entirely the same:- They removed the support of multiple keylengths (only support 32 byte keys atm). Some functions still have arguments for it, but are not used
- They removed the support for different cryptography methods (CBC, ECB, CFB), only OFB is used
- Some functions have different arguments types
The last part is what makes the bug happen. In the original AES implementation, the key initialization function (AES_EncKeySchedule and AES_DecKeySchedule) had the following arguments:
- BYTE* UserKey
- AES_ALG_INFO* AlgInfo
However, in MapleStory, they are not asking for a BYTE* UserKey, but an DWORD* UserKey!
This is probably something that they broke when they started to remove all redundant code and tried to make the original code better, because of the following:
Original RIJNDAEL_KeySchedule has the following arguments:
- BYTE* UserKey
- DWORD k_len
- DWORD* e_key
The modified variant has:
- DWORD* UserKey
- DWORD* e_key
As the code does not support key lengths anymore, the arguments changed. Its possible that they removed the code in RIJNDAEL_KeySchedule, but because the arguments didnt match, they accidentally changed the type from BYTE* to DWORD*...
The change of the argument triggers the following issue:
Code:
// Correct input:
BYTE* UserKey[] = new BYTE[32] {
0x13, 0x52, 0x2A, 0x5B, 0x08, 0x02, 0x10, 0x60,
0x06, 0x02, 0x43, 0x0F, 0xB4, 0x4B, 0x35, 0x05,
0x1B, 0x0A, 0x5F, 0x09, 0x0F, 0x50, 0x0C, 0x1B,
0x33, 0x55, 0x01, 0x09, 0x52, 0xDE, 0xC7, 0x1E
};
DWORD* e_key = new DWORD[8];
// copy 4 bytes from the UserKey into e_key (quick machine operation)
e_key[0] = *(DWORD*)UserKey[0];
e_key[1] = *(DWORD*)UserKey[4];
e_key[2] = *(DWORD*)UserKey[8];
e_key[3] = *(DWORD*)UserKey[12];
e_key[4] = *(DWORD*)UserKey[16];
e_key[5] = *(DWORD*)UserKey[20];
e_key[6] = *(DWORD*)UserKey[24];
e_key[7] = *(DWORD*)UserKey[28];
// Correct value of e_key:
DWORD* e_key = new DWORD[8] {
0x5B2A5213,
0x60100208,
0x0F430206,
0x05354BB4,
0x095F0A1B,
0x1B0C500F,
0x09015533,
0x1EC7DE52
};
But the following is happening
Code:
DWORD* UserKey = new DWORD[32] {
0x13, 0x52, 0x2A, 0x5B, 0x08, 0x02, 0x10, 0x60,
0x06, 0x02, 0x43, 0x0F, 0xB4, 0x4B, 0x35, 0x05,
0x1B, 0x0A, 0x5F, 0x09, 0x0F, 0x50, 0x0C, 0x1B,
0x33, 0x55, 0x01, 0x09, 0x52, 0xDE, 0xC7, 0x1E
};
DWORD* e_key = new DWORD[8];
// copy 1 DWORD from the UserKey into e_key (quick machine operation)
// Note that the offset from UserKey stays the same, actively skipping 3 DWORDs
e_key[0] = UserKey[0]; // 0x00000013
e_key[1] = UserKey[4]; // 0x00000008
e_key[2] = UserKey[8]; // 0x00000006
e_key[3] = UserKey[12]; // 0x000000B4
e_key[4] = UserKey[16]; // 0x0000001B
e_key[5] = UserKey[20]; // 0x0000000F
e_key[6] = UserKey[24]; // 0x00000033
e_key[7] = UserKey[28]; // 0x00000052
// Resulting e_key
DWORD* e_key = new DWORD[8] {
0x00000013,
0x00000008,
0x00000006,
0x000000B4,
0x0000001B,
0x0000000F,
0x00000033,
0x00000052
};
And that, kids, show that you should carefully refactor your code. And write tests, because this wouldn't have happend if there were tests involved.
Or this is to reduce the effectiveness of AES in order to make the NSA sniff the MapleStory connections. But thats not possible with the Shanda encryption.
However, its removed from maple. Why is it removed?
And why the random UserKey now?
Last edited: