Encryption
RSA-2048 handshake + AES-128-GCM transport encryption.
Handshake
The client generates a random 16-byte AES key, encrypts it with the server's RSA public key, and sends a 268-byte handshake packet:
[key_size: 4 LE = 256][key_encrypt_type: 4 LE = 16][encrypt_type: 4 LE = 3][encrypted_key: 256]| Field | Value | Description |
|---|---|---|
key_size | 256 | RSA-2048 output size in bytes |
key_encrypt_type | 16 (0x10) | RSA-OAEP SHA-1 |
encrypt_type | 3 | AES-128-GCM |
encrypted_key | 256 bytes | RSA-encrypted AES key |
[!WARNING]
key_encrypt_typemust be 16, not 15. This single-bit difference determines whether the server accepts the handshake.
RSA Parameters
| Parameter | Value |
|---|---|
| Key size | 2048-bit |
| Exponent (e) | 3 |
| Padding | OAEP |
| Hash | SHA-1 (not SHA-256) |
| Key format | DER/PKCS#1 Base64-encoded in the binary |
The RSA public key is extracted from /Applications/KakaoTalk.app/Contents/MacOS/KakaoTalk.
AES-128-GCM Transport
After the handshake, all data is encrypted with AES-128-GCM:
[size: 4 LE][nonce: 12][ciphertext + GCM tag: N + 16]| Component | Size | Description |
|---|---|---|
| Size prefix | 4 bytes | Total size of nonce + ciphertext + tag |
| Nonce | 12 bytes | Random, unique per frame |
| Ciphertext | N bytes | Encrypted LOCO packet data |
| GCM tag | 16 bytes | Authentication tag |
Each packet and each file upload chunk uses a fresh random nonce to prevent nonce reuse.
Fragility Warning
The handshake constants (key_encrypt_type = 16, encrypt_type = 3) are not documented by Kakao and were determined through reverse engineering. These values are fragile:
key_encrypt_typemust be exactly 16 (0x10), not 15 (0x0F). The difference is a single bit, and the wrong value causes a silent handshake rejection. This has been a recurring source of confusion in third-party implementations.encrypt_typemust be exactly 3 (AES-128-GCM). The server does not negotiate or fall back. Sending 2 (the old CFB mode) results in a rejected connection.- RSA exponent
e = 3is unusual (most implementations default to 65537). If your RSA library does not supporte = 3, the handshake will fail. - SHA-1 for OAEP padding is required. SHA-256 OAEP will produce a valid-looking ciphertext that the server silently rejects.
These constants can change without notice in a KakaoTalk app update. If connections start failing after an app update, re-extract the RSA public key from the new binary and check whether any handshake constants have changed.
Historical Note
Earlier versions of KakaoTalk used encrypt_type = 2 (AES-128-CFB). The current version uses encrypt_type = 3 (AES-128-GCM), which provides authenticated encryption.