Skip to content

Instantly share code, notes, and snippets.

@Baw-Appie
Created March 17, 2026 11:24
Show Gist options
  • Select an option

  • Save Baw-Appie/4e76daf98d9b1b1c7da4a1b474af1d90 to your computer and use it in GitHub Desktop.

Select an option

Save Baw-Appie/4e76daf98d9b1b1c7da4a1b474af1d90 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
"""Test different decryption configurations for KakaoTalk database."""
# from pysqlcipher3 import dbapi2 as sqlite
import hashlib
import base64
from pathlib import Path
import subprocess
def get_device_uuid():
"""Get the Mac's hardware UUID."""
result = subprocess.run(
["ioreg", "-d2", "-c", "IOPlatformExpertDevice"],
capture_output=True, text=True
)
for line in result.stdout.split('\n'):
if 'IOPlatformUUID' in line:
return line.split('"')[-2]
raise Exception("Could not get device UUID")
def pbkdf2(password: bytes, salt: bytes):
return hashlib.pbkdf2_hmac("sha256", password, salt, 100000, 128)
def hashedDeviceUUID(uuid: str):
uuid_bytes = uuid.encode("ascii")
return base64.b64encode(
hashlib.sha1(uuid_bytes).digest() + hashlib.sha256(uuid_bytes).digest()
).decode("ascii")
def getDatabaseName(userId: int, uuid: str):
hawawa = ".".join([
".", "F", str(userId), "A", "F",
"".join(reversed(uuid)), ".", "|",
])
return pbkdf2(
hawawa.encode("ascii"),
"".join(reversed(hashedDeviceUUID(uuid))).encode("ascii")
).hex()[28:28+78]
def getSecureKey(userId: int, uuid: str):
hawawa = "F".join([
"A", hashedDeviceUUID(uuid), "|", "F",
uuid[:5], "H", str(userId), "|", uuid[7:]
])
return pbkdf2(
"".join(reversed(hawawa)).encode("ascii"),
uuid[int(len(uuid) * 0.3):].encode("ascii")
).hex()
def find_user_id_from_cache():
"""Try to find user ID from cache database."""
import sqlite3
cache_path = Path.home() / "Library/Containers/com.kakao.KakaoTalkMac/Data/Library/Caches/Cache.db"
if not cache_path.exists():
return None
conn = sqlite3.connect(str(cache_path))
cursor = conn.cursor()
cursor.execute("SELECT request_key FROM cfurl_cache_response WHERE request_key LIKE '%bzm-capi%'")
for row in cursor.fetchall():
url = row[0]
if '/client/' in url:
parts = url.split('/client/')
if len(parts) > 1:
user_id = parts[1].split('/')[0]
if user_id.isdigit():
conn.close()
return int(user_id)
conn.close()
return None
def find_database():
"""Find the active KakaoTalk database."""
base_path = Path.home() / "Library/Containers/com.kakao.KakaoTalkMac/Data/Library/Application Support/com.kakao.KakaoTalkMac"
# Find the largest database file (most likely active)
db_files = []
for f in base_path.iterdir():
if f.is_file() and len(f.name) == 78: # Database name length
db_files.append((f, f.stat().st_size))
if db_files:
db_files.sort(key=lambda x: x[1], reverse=True)
return db_files[0][0]
return None
def hashedDeviceUUID(uuid: str):
uuid_bytes = uuid.encode("ascii")
return base64.b64encode(
hashlib.sha1(uuid_bytes).digest() + hashlib.sha256(uuid_bytes).digest()
).decode("ascii")
def getSecureKey(userId: int, uuid: str):
hawawa = "F".join([
"A", hashedDeviceUUID(uuid), "|", "F",
uuid[:5], "H", str(userId), "|", uuid[7:]
])
return pbkdf2(
"".join(reversed(hawawa)).encode("ascii"),
uuid[int(len(uuid) * 0.3):].encode("ascii")
).hex()
secure_key = getSecureKey(find_user_id_from_cache(), get_device_uuid())
print(f"Secure Key: {secure_key}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment