Dark Chocolate Software, LLC
Apps made using pure, undiluted, cocoa

Annals Security

The primary goal of Annals was safe, easy, and secure journal keeping.
This page will explain how we protect data.

First and foremost, all encryption, decryption, hashing, and random generation is done by the system library, CommonCrypto.

All encryption is done using AES128 with a 256bit key, and hmac computation is done using SHA256, and key generation hashing uses SHA512.

Each shelf is protected by a seperate password, so that cracking one shelf won't get them every entry in every shelf.

This password is used to protect the encryption keys for each shelf.
It is run through PBKDF2 a large number of times to generate a derived key and a derived hmac key, and to slow down key guessers.
This is used to decrypt the master key, master hmac, overview key and overview hmac.
Each item, and its associated attachments are encrypted using per item keys.
Data we need more frequently such as tags and locations are encrypted with the overview key.

Key generation

To generate the master, overview and per item keys, we use SecRandomCopyBytes to get enough bytes for both our key and hmac pair, then this data is hashed with more random data to generate the keys.

Data Format

All symmetricaly encrypted data follows the following format:
  • A prefix of 8 bytes representing andata01
  • Little endian UInt64 bytes representing the length of the unpadded data
  • 16 bytes of randomly generated IV
  • Padded encrypted data, padded out to the block size for AES128, enough to fill it out to an even division of the block size, or a full additional blocksize
  • The hash of all the proceeding data
Attachment data is written out to disk as a seperate file
All other data is converted to Base64 and stored in the database or backups as text

We keep only unlocked and in memory what needs to be unlocked for basic display


QuickEntry is an optional system for providing creation of entries on a shelf without unlocking it using a public/private key pair. QuickEntry's key pair is created using Apple's SecKeyCreateRandomKey, with settings to create a 2048 bit RSA pair. QuickEntry's public key is stored as plain text data, and it's private key is stored encrypted using the shelf master key.

Additionally, we store information about key type and size, so that should upgrades in algorithm or key size be needed, we can do that

When an entry is created using QuickEntry, an entry key is generated as normal, and used to encrypt the entry, and any attachments. However, instead of the entry key being encrypted with the shelf master key and stored as above, it is encrypted using the shelf public key. We use Apple's SecKeyCreateEncryptedData to do the encryption using the 'kSecKeyAlgorithmRSAEncryptionOAEPSHA512AESGCM' constant, which generates a 128 bit AES session key to encrypt the entry key with, and then encrypts the session key using the public key.

When a shelf is unlocked, the entry keys of any QuickEntry entries are decrypted using the private key (using the reverse of the above), and then reencrypted using the symmetric shelf master key.

QuickEntry support is per shelf, and also per device for all shelves on that device. You will be asked if you wish to enable QuickEntry on each device when you unlock a shelf with it enabled, and it can be turned on or off at any time in the settings.

On the Mac, QuickEntry is done via a helper process that controls syncing and can run as a status item. This helper has no access to your decryption keys, and communicates with the main app via a secure XPC service.

Potential threats

So, you are concerned about your journals, they have very private data. What are the possible threats.

The two most likely threats are a weak or easily guessed password, or that we screwed up. We do our best to ensure the safety and integrity of your data, but we won't try to claim perfection.

Next is an unlocked journal on a device, export functions are password protected, but the master keys of any unlocked shelves are already in memory.

There is also a possibility of inferrence drawing via the unencrypted meta data

  • Shelf names are unencrypted so that we can display them on the login screens
  • Entry date stamps and time-zone ID's are unencrypted for speed of loading the entry list.
  • Links between tags, locations, attachments and entries are visible
  • Actual tag name is encrypted (and a hashed version for search purposes)
  • Specific location data is encrypted, and a less accurate version is hashed for searching purposes


Attachments are previewed using system preview tools (QuickLook plugins) on both iOS and macOS. For a lot of standard file types, these plugins are provided by Apple. However, third party plugins can override these, and aren't as secure, and you need to be aware of what plugins are in use on your system.

Metadata is stored encrypted using the overview key described above. Metadata includes, at the moment, its original filename and universal type identifier (UTI) for the purposes of preview and display. When attachments are made using QuickEntry, the metadata is temporarily encrypted using the public key and is reencrypted upon unlock of the shelf using the overview key.

Additionally, whether a file is a picture or a generic attachment is stored in plain text (as a number) for the purposes of easier filtering of pictures vs files.

Syncing and iCloud

There is a final possibility, and that is if you choose to use iCloud to sync, and someone compromises the layers of protection surrounding that, and then gets through all of the above as well

We chose to use Apple's CloudKit for two main reasons. Ease of use, and security

We already have experience syncing with CloudKit so the libraries were similar. Syncing is fast and easy for the kind of data we store

But what of security you say? It's the cloud, surely it isn't secure

First, all of the above happens on your devices, before we ever store it on the device, much less sync anything to Apple's end. Second, communication with iCloud happen's exclusively over https, using Apple's own libraries. Third, all Annals data is stored in your private database, and is encrypted on their servers using your account's keys.

For more information on iCloud security, see Apple's white paper

Best practices

There are some steps one can take to increase the security of one's journals and devices in general.

  • First, use a strong password, we won't list the whole littany of password strength techniques, but unique, long, mix of letters, numbers and symbols.
  • For super strong passwords, we recommend creating and storing them in an app such as 1Password
  • Second, use strong passwords on your devices and iCloud account. TouchID and FaceID is good for quick access, but behind it should be a strong unique password, not a 4 digit pin.
  • If you are concerned about TouchID or FaceID, it's use in Annals for iOS is completely optional
  • Enable iCloud two factor authentication, and any other services you might use.
  • Do not jailbreak your device, and be careful what software you run on your Mac and iOS devices, including QuickLook plugins.

This is by no means a list of every security precaution, but its a good starting point