Today, I'm going to explain one of the most critical parts in KakaoTalk: Session Key.
KakaoTalk has only one mechanism to authenticate the user. It is the session key that is generated in the process of registering yourself to the KakaoTalk server when you first install on your mobile device. This, then, is stored in the device until the user deletes KakaoTalk.
What's interesting here is that this session key acts as user identification AND user authentication on server side. Thus, this session does not act the same as the usual 'web' session keys, which expires after some time. KakaoTalk Session Key never expire or change -- well, I shouldn't say 'never' because there's a case that the key is purged. It is used throughout until the user deletes his/her account or KakaoTalk app from the phone. (BTW, deleting an app doesn't cause the account to be deleted.)
As you saw last time, the Session Key is required for every request that is sent to the server, and included in HTTP header with the field name of 'S'.
So, how is this key generated, and what does the life cycle of the key look like?
1. Session Key Generation
- Session Key is consisted of two parts: X-Y
- First part (X) is generated during the SMS verification in registration step.
- I tested on Android KakaoTalk, and the following is the steps in detail what's happening in the process of the verification.
- Client requests a SMS verification to KakaoTalk server (ac-talk.kakao.com)
- This is done through /android/account/request_sms.json
- POST data: device_uuid, phone_number, country_iso - Server responds with the one-time 'token' in json format
- Meanwhile, the server also sends actual SMS message (which contains passcode) to the number. - Once the user puts in the passcode, the client submits to the server.
- /android/account/verify_sms.json
- POST data: token (to verify it's you), phone_number, country_iso, passcode, device_uuid, old_session_key
- Here, old_session_key is set when you have changed your phone but still has old_session_key backed up in the system. - Server responds with status code '11' and a new token is returned when successful.
- Finally, the client requests [/android/account/verify.json] along with the nickname that the user specified.
- POST data: phone_number, country_iso, device_uuid, new token, nickname, old_session_key - The server generates and sends 'sessionKey' in JSON data with other information as well.
- JSON data includes: sessionKey, 'member' object (type is set to -10, which means it's myself), userid (unique number that differentiates users), nickname, etc. - At this point, the session key has been given to the client, and the client saves it locally.
- The subsequent requests must contain this session key, otherwise the request is rejected with error code -500 (session key not specified). - Client then sends a query to [/android/account/update_settings.json] to sync the information on the server and the client.
- POST data: model, simOperator, screen_resolution, os_name, os_version, etc.
- I wonder why they need all this much information. - I haven't tested on iPhone, but it's just basically the same with different URL for iPhone.
- Second part (Y) is generated based on the device id.
- On Android:
- This is just plain device ID, it seems. But I haven't done much reversing on this part, so I may be slightly wrong :p
- On iPhone:
- It uses something called 'encryptedDeiceID' which it derives from the property named 'cryptedUniqueIdentifider' (notice their typo :p)
- Again, as the name indicates, it does something with the device ID, but I haven't reversed this part yet.
- The reason I didn't go deep enough to actually understand how they generate the device ID is because while it's still possible to reverse engineer and reconstruct the encrypted device ID, there's no way to reconstruct the first part of the session key since it comes directly from the server.
- Thus, unfortunately, there doesn't seem to be a good way to regenerate the session key. Once it's generated and given to the client, both client and server just save it locally and use that to authenticate.
- As I mentioned above, the usage of the session key is blatantly obvious. They use it to authenticate. Once it's set, it never changes -- unless the device is changed.
- The session key must be included to the request header.
- If the device ID changes (due to changing the device, etc.), KakaoTalk asks the user to re-verify the mobile device. In this process, old_session_key is set to the previous session key and the newly generated session key is returned.
- Session Revocation
- I was little surprised and impressed that KakaoTalk does this correctly ;)
- When the user verifies with the existing (same) number, KakaoTalk server revokes (deletes) old association with the account and the session key.
- Thus, it is not possible to impersonate a user with his/her old session key.
- Local storage of the key:
- Android: /data/data/com.kakao.com/shared_prefs/KakaoTalk.perferences.xml
- iPhone: /User/Applications/XXXXX...XXXX/Library/Preferences/com.iwilab.KakaoTalk.plist
I mean, their one-factor, fixed token authentication mechanism scares me a little, but I had an impression that they actually somewhat care about security. However, they would need to come up with the better solution to this, since it's basically game-over situation if someone is able to extract the session key. (You can basically become anyone, and KakaoTalk wouldn't know shit.)
Anyways, that's what I have and know about KakaoTalk's session key system.
I don't know how they generate the first part, so I wouldn't go ahead and reverse the algorithm for the second part. If someone knows more about this, feel free to contact me! Maybe we can collaborate to do cool things :p
Thanks for reading!




N@R_2차_문제풀이_Cai.pdf
rss
개인적으로 내린적은 없는데 말이죠 ㅎㅎ
사실 요즘은 연구실 상황이 좀 바빠서 이쪽은 거의 손을 못대고 있네요 ㅎㅎ
말씀하신것을 해본적은 없구요, 사실 해서 얻을게 그리 없기때문에.. :)
시간이 나는대로 아예 바이너리 레벨에서 SSL을 없애는 방법에 대해서 쓸까 합니다.. 요즘 너무 바빠서 시간이 안나네요 ㅠㅠ