Skip to content
Back to skills

wechat-key-macos

ASecurity

Extract SQLCipher database keys from WeChat for Mac 4.x (tested 4.1.13) so its local chat databases can be decrypted and queried. Use when a user on macOS wants to read/decrypt/export their own local WeChat data and existing tools (e.g. wechat-cli, wechat-decrypt) fail with 0 keys / "cannot decrypt" because they only support WeChat <= 4.1.8. Runtime: macOS (Apple Silicon or Intel), Python 3.10+, frida < 17, pycryptodome; requires sudo and a running, logged-in WeChat that has been ad-hoc re-si...

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 23, 2026
ai-agentspythonrustbashsqldatabasesecurity

Works with

  • terminal
  • cli

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 8 files and shows the line behind each finding

Scanned September 23, 2026

npx -y skills add 3351666087/wechat-key-macos --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of wechat-key-macos?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for wechat-key-macos
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/3351666087-wechat-key-macos/badge)](https://www.skillsdirectory.com/skills/3351666087-wechat-key-macos)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: wechat-key-macos
version: 1.0.0
description: >-
  Extract SQLCipher database keys from WeChat for Mac 4.x (tested 4.1.13) so its
  local chat databases can be decrypted and queried. Use when a user on macOS
  wants to read/decrypt/export their own local WeChat data and existing tools
  (e.g. wechat-cli, wechat-decrypt) fail with 0 keys / "cannot decrypt" because
  they only support WeChat <= 4.1.8. Runtime: macOS (Apple Silicon or Intel),
  Python 3.10+, frida < 17, pycryptodome; requires sudo and a running, logged-in
  WeChat that has been ad-hoc re-signed with get-task-allow.
license: Apache-2.0
compatibility:
  os: macOS 13+ (tested 26.6.2)
  arch: [arm64, x86_64]
  wechat_mac: "4.0 – 4.1.13 (tested 4.1.13)"
  python: ">=3.10 (tested 3.14)"
  pins:
    frida: "<17 (tested 16.7.19)"      # frida 17 removed the built-in JS bridges this relies on
    pycryptodome: ">=3.19"
---

# wechat-key-macos

Extract per-database SQLCipher keys from a **running WeChat for Mac 4.x** and use
them to decrypt/query the local databases. This is agent-agnostic: any coding
agent (or a human) can follow it.

## When to use

Use this skill when, on macOS, the user wants to read/query/export **their own**
local WeChat data and a key-extraction step fails on a modern WeChat build —
symptoms: `提取到 0 个密钥` / "extracted 0 keys", `无法解密 session.db` / "cannot
decrypt", or a memory scan that finds no `x'...'` pattern. Those tools assume
WeChat ≤ 4.1.8; this skill handles 4.x (verified on **4.1.13**).

Only operate on the machine's own logged-in account, at the user's request.

## Why the old method fails on 4.x (one paragraph)

WeChat ≤ 4.1.8 left the SQLCipher raw key in memory as an ASCII PRAGMA string
`x'<64 hex key><32 hex salt>'`, so tools scanned for it. WeChat 4.x no longer
keeps that string resident, and the derived keys are not reliably recoverable as
aligned raw bytes either. **Each database now has its own key**
`enc_key_i = PBKDF2-HMAC-SHA512(password, salt_i, 256000, 32)` (salt = first 16
bytes of each file; the account `password` is shared across all DBs). The
reliable, version-robust way to obtain the keys is to hook the system crypto
functions WeChat calls at runtime — see `reference/method.md`.

## Method (what the script does)

Hook macOS **CommonCrypto** with Frida on the live WeChat process:

- `CCCrypt`, `CCCryptorCreate`, `CCCryptorCreateWithMode` — SQLCipher calls these
  to AES-decrypt **every database page**, passing the 32-byte derived key. WeChat
  reads its DBs constantly, so keys stream in with no special trigger. Each
  captured key is verified against every database's page-1 HMAC-SHA512 to map it
  to a database.
- `CCKeyDerivationPBKDF` — if a key derivation happens (e.g. a DB is opened during
  capture), this yields the **password** directly, letting us derive keys for all
  databases at once.

SQLCipher parameters (WeChat 4.x): AES-256-CBC, page size **4096**, reserve **80**
(= 16-byte IV + 64-byte HMAC-SHA512), KDF **PBKDF2-HMAC-SHA512 × 256000**, HMAC
subkey via `PBKDF2(enc_key, salt XOR 0x3a, 2)`, per-database salt.

## Prerequisites (do these first)

1. **Full Disk Access** for the terminal: System Settings → Privacy & Security →
   Full Disk Access → add Terminal/iTerm → restart it.
2. **WeChat running and logged in.**
3. **Make WeChat debuggable (once).** If attaching or `task_for_pid` fails,
   ad-hoc re-sign WeChat with `get-task-allow`, then fully quit & reopen WeChat:
   ```bash
   sudo codesign --force --sign - \
     --entitlements /dev/stdin /Applications/WeChat.app <<'EOF'
   <?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
   <plist version="1.0"><dict>
     <key>com.apple.security.get-task-allow</key><true/>
   </dict></plist>
   EOF
   ```
   Re-signing is local and reversible (reinstall WeChat to revert). It does not
   affect the account.
4. **Install deps** (note the pins):
   ```bash
   python3 -m pip install 'frida<17' pycryptodome
   ```

## Steps

1. Ensure prerequisites above.
2. Run the extractor as root:
   ```bash
   sudo python3 scripts/extract_key.py            # auto-detects db_storage
   # or: sudo python3 scripts/extract_key.py --db-dir "<...>/db_storage" --wait 240
   ```
3. **While it runs, interact with WeChat** — open several chats, Contacts,
   Favorites, Moments, the sticker panel, and use search. Each feature reads its
   database, which makes SQLCipher decrypt pages and thus reveals that DB's key.
   You'll see `[FOUND] <db> enc_key=...` lines.
4. It writes `keys.json` = `{ "rel/path.db": { "enc_key": "<hex>", "salt": "<hex>", "size_mb": N }, ... }`.
   Databases not read during the window won't be covered — re-run after opening
   those features to fill them in.
5. To also produce decrypted, plaintext SQLite files:
   ```bash
   sudo python3 scripts/extract_key.py --decrypt ./decrypted
   ```
   Then open `./decrypted/message/message_0.db` etc. with any SQLite tool, or use
   the bundled `wechat-cli/` to query (it consumes the same key format at
   `~/.wechat-cli/all_keys.json`).

## Verifying a key without reading private data

Decrypt only page 1 and check the SQLite header — no chat content is exposed:
```python
from scripts.extract_key import decrypt_page  # header should be b"SQLite format 3\x00"
```

## Output contract

`keys.json`: object keyed by database path relative to `db_storage`, each value
`{ "enc_key": <64 hex = 32-byte AES-256 key, used directly>, "salt": <32 hex>,
"size_mb": <float> }`. `enc_key` is the final AES key (no further derivation).

## Troubleshooting

- **`aes_keys_seen` stays 0** → WeChat didn't call CommonCrypto during capture, or
  attach didn't take. Confirm sudo + re-signed WeChat; keep clicking in WeChat.
- **frida `ObjC` / bridge / attach oddities** → you're on frida ≥ 17. Pin `frida<17`.
- **`task_for_pid failed`** → do the re-sign step, then fully quit & reopen WeChat.
- **pip TLS errors behind a filtering proxy** → add
  `--trusted-host pypi.org --trusted-host files.pythonhosted.org`.
- **Keys extract but decryption looks wrong** → confirm page size 4096 / reserve 80;
  a future WeChat could change these (see `reference/method.md`).

## Safety / scope

Local, read-only with respect to WeChat's data. Operate only on the user's own
machine and account, at their explicit request. Never upload databases or keys.
See `README.md` disclaimer.

Files in this skill

  • SKILL.md6.4 KB
  • reference/method.md6.5 KB
  • scripts/extract_key.py14.3 KB
  • scripts/requirements.txt213 B
  • wechat-cli/LICENSE11.1 KB
  • wechat-cli/PATCHED.md2 KB
  • wechat-cli/entry.py135 B
  • wechat-cli/pyproject.toml470 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…