While analyzing a test device with a popular commercial mobile forensic tool, I came across something intriguing—a locked Apple Note that appeared only as “hidden.” The tool showed the note’s summary (labeled “Lance”), but the actual content was missing. There was no clue what lay beneath the lock, leaving me with a burning question: could I uncover the secret inside? I needed a workflow that would help me decrypt Apple Notes on iOS 16.
The device was running iOS 16.7.10, and after digging into the NoteStore.sqlite database, I realized all the encryption clues were sitting right there—waiting to be decoded. With the help of open-source tools, I set out to recover the password and decrypt the note’s contents.
This post walks you through the complete forensic workflow on how to decrypt Apple Notes on iOS 16:
⚠️ Important Note: This workflow applies specifically to Apple Notes locked on iOS 16.x. Starting with iOS 17, Apple changed how encrypted notes are stored—and iOS 18 brings even further changes.
Let’s dive in and reveal the hidden message inside that locked Apple Note.
In the screenshot, you can see the raw hexadecimal values for ZDATA. This data is effectively scrambled by AES encryption, with critical metadata—like salts and iteration counts—saved in other parts of the database. From a forensic examiner’s perspective, recognizing that the note is fully encrypted is your cue to dig deeper into the ZICCLOUDSYNCINGOBJECT table for the parameters needed to crack the passcode and unlock the note 🔓.
Apple Notes secures locked notes using a combination of PBKDF2 (key derivation) and AES (encryption). When a password is enabled on a note, Apple stores key cryptographic metadata in the database—such as:
These values ensure that only someone with the correct passcode can decrypt the note’s content.
From a forensic standpoint, your steps typically include:
My goal was to simulate a realistic forensic scenario: I had a locked Apple Note and needed to recover its passcode to decrypt the content. That’s where Hashcat comes into play. Leveraging its Apple Secure Notes hash mode (ID 16200), Hashcat systematically attempted passwords until it found the correct one.
I began by opening NoteStore.sqlite in DB Browser and targeting rows with ZISPASSWORDPROTECTED = 1 in the ZICCLOUDSYNCINGOBJECT table. I then queried the following columns:
The Hashcat input file was generated by a small Python script notes_to_hashcat.py, which formatted these values into a single line that Hashcat could parse, including the iteration count (from ZCRYPTOITERATIONCOUNT).
With my Hashcat input file ready and a dictionary on hand, I ran the following command:
hashcat -m 16200 -a 0 <C:\path_to_hashcat_input.txt> <C:\path_to_wordlist.txt>
Here:
Hashcat successfully identified the correct password: royalewithcheese. In an actual investigation, your dictionary might be far larger, but this result confirmed that Hashcat could handle the heavy lifting.
With the password in hand, the next step was to derive the Key Encryption Key (KEK), which is used to wrap the final AES key that encrypts the note’s content. To derive the KEK, I needed the following values from the ZICCLOUDSYNCINGOBJECT table:
For example, using DB Browser, I queried:
SELECT ZCRYPTOITERATIONCOUNT, ZCRYPTOSALT FROM ZICCLOUDSYNCINGOBJECT WHERE Z_PK = <your_locked_note_pk>;
Next, I opened CyberChef—a favorite tool of mine 🛠️—and dragged in the “Derive PBKDF2 key” operation. Setting the hashing function to SHA-256 and inputting the password, salt, and iteration count, CyberChef produced the 16-byte KEK:
To automate this process, I created a Python script called get_key.py, which accepts the database path, note PK, and password as arguments. Running it returns the KEK in hex.
python get_kek.py NoteStore.sqlite <Z_PK> <password>
Result:
Note PK=16: KEK (hex) = a1dac1516302e1d3d73ad4fd4b6f8fef
The next step was to unwrap the key used to encrypt the note’s content. The wrapped key is stored in the ZCRYPTOWRAPPEDKEY column of ZICCLOUDSYNCINGOBJECT. For example, I queried::
SELECT ZCRYPTOWRAPPEDKEY FROM ZICCLOUDSYNCINGOBJECT WHERE Z_PK = 16;
I disabled any previous operations, searched for “AES Key Unwrap,” and dragged it into the recipe window. By pasting in the KEK and wrapped key, CyberChef output the unwrapped AES key.
I also developed a Python script called unwrap.py which takes the database path and KEK (in hex) as arguments. Running this script unwrapped the key and printed it in hex format. In my case, the unwrapped key was:
python unwrap.py NoteStore.sqlite <KEK>
This is the final AES key that will be used to decrypt the locked Apple note’s content.
Now that I had the unwrapped key, it was time to decrypt the Apple Notes BLOB stored in the ZICNOTEDATA
table. Apple uses AES in GCM mode to protect the contents of locked notes, which means I needed four essential components to proceed:
🔑 Unwrapped AES Key
🔁 Initialization Vector (IV) from ZCRYPTOINITIALIZATIONVECTOR
🏷 GCM Authentication Tag from ZCRYPTOTAG
💾 Encrypted BLOB from ZDATA
To locate the IV and GCM tag, I opened the ZICNOTEDATA
table in DB Browser for SQLite. These fields are stored as binary values and can be found in either the ZICNOTEDATA
or ZICCLOUDSYNCINGOBJECT
tables. Both store the data under the same column names.
IV: 5c0c0bde9b6801747ddad1115a422d05
GCM Tag: b9087ba19e3c7deff2cb4b9b51e6aafa
The encrypted BLOB itself was also visible in the ZDATA
column. I copied all three values in hexadecimal format, preparing for the final decryption step.
With everything in hand, I turned to CyberChef. This tool made it easy to combine all the parameters and reveal the original content. Here’s what I did:
I added the “AES Decrypt” operation.
I pasted the unwrapped AES key into the Key field.
I set the mode to GCM.
I inserted the IV and GCM Tag into their respective fields.
Finally, I copied the encrypted BLOB into the input window.
After decrypting the AES-encrypted BLOB, I saved the output to a file named decrypted_blob.bin
and opened it in HxD. The file signature 0x1F8B08
confirmed it was a GZIP-compressed file—Apple uses this to compress protobuf data.
To extract the plaintext, I reopened CyberChef and added the Gunzip operation to the workflow. Immediately, familiar strings began to appear in the output.
Once uncompressed, I applied Protobuf Decode in CyberChef. The result was a structured view resembling JSON, with keys and values representing the contents of the locked Apple Note.
For easier reading, I also used a Python script that leveraged the backboxprotobuf
module to parse the protobuf file and print the output in a clean, human-readable format.
This matches what the user typed in their locked Apple Note. You’ve gone from a hidden, password-protected entry to the actual, plaintext message—an invaluable find in any forensic case.
Congratulations 🎉 — you’ve just completed a full forensic workflow to decrypt locked Apple Notes on iOS 16. You extracted encryption parameters from the SQLite database, cracked the password with Hashcat, derived and unwrapped the AES key using Python, and finally decrypted and parsed the protobuf with CyberChef. Each step brought you closer to exposing the note’s hidden contents.
This hands-on walkthrough proves how powerful open-source tools can be in digital forensics. They help investigators uncover encrypted Apple Notes that commercial tools might miss — especially on devices running iOS 16 or earlier.
Here’s an extra twist — I found a password hint in the ZICCLOUDSYNCINGOBJECT
table:
Quarter Pounder
Since the device belonged to someone named “Vincent,” it wasn’t hard to guess the password: royalewithcheese — a nod to Pulp Fiction. In real cases, password hints like this can accelerate the workflow when combined with a strategic cracking process.
This guide applies specifically to how to decrypt Apple Notes on iOS 16 and earlier. Starting with iOS 17, Apple introduced significant changes to the Notes encryption process. You may encounter missing key derivation fields, different cryptographic structures, or notes that no longer decrypt using the same methods.
If you’re exploring how to decrypt Apple Notes on iOS 17 or iOS 18, I’d love to collaborate. Share your findings — let’s break down the new encryption together.
Thanks for reading! Got questions or insights? Drop them in the comments below or reach out directly. Let’s keep pushing the boundaries of forensic discovery. 🔍