Exploring Secure Notes in the Mac OS X Keychain

So I was exploring the Mac OS X Keychain API and looking into the available methods, however I noticed that there was no way to access a Secure Note that you can create in the Keychain Access.app application.

A Secure Note, like its name implies is just a secure piece of text that is stored into your keychain. You create one by going to Keychain Access.app, File -> New Secure Note Item, and then fill out the fields.

If you double click a Secure Note, you view its properties, like so:

But looking at the Keychain Services API again, there is nothing that immediately stands out to retrieving the content of a Secure Note. The 'easy to use APIs' are limited to SecKeychainFindGenericPassword() and SecKeychainFindInternetPassword(). Upon searching, I came across the security command line tool provided by Apple. Again, looking at the available options there is nothing relating to Secure Notes at all.

More searching, and it turns out that Secure Notes are implemented as just a "Generic Password" in the keychain, and its just Keychain Access.app that handles the creation and viewing of the Secure Notes. So how exactly do you get them out? You can use the security tool, with the find-generic-password feature, but you need to provide some specifics. Keychain entries have a notion of a 'creator', which is actually a 4 character string, which makes sense as that is how Mac used to identify what program would open a file.

The four character code for Secure Notes is, 'note', unsuprisingly. We also need to know the "Service String", which is used to identify what this generic password is for, and this happens to be the title of the Secure Note. This is also why you cannot have two secure notes with the same title, as the Service String is how the keychain distinguishes different Secure Notes from each other.

So, running the command security find-generic-password -C note -s "Testing Note", you get some output displaying metadata about the generic password (the Secure Note) that was the result of the search result.

You notice that you don't see the "password" content, or the text of your Secure Note in this output. For that, we either need to pass the -g option to output the password bytes (in base64, and its attempt at decoding it), or just pass -w, which just outputs the password bytes only in base64. So running security find-generic-password -C note -s "Testing Note" -w will just output:

Writing a quick python3 script to decode the base64 encoding, and loading the result as XML as noticed in the -g output that it is a property list:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

#!/usr/bin/env python3importxml.etree.ElementTreeasETimportplistlib,pprint,binascii# not full hex string for brevity!hex_data='''3c3f786d6c2076657273696f6e3d22312e3022206....'''# decode hex into bytesxml_bytes=binascii.unhexlify(hex_data)# create ElementTree object since its an XML PListET.fromstring(xml_bytes)# print out xmlprint(ET.tostring(xml_bytes))# or you can load it straight into a python object using plistlibplist_dict=plistlib.loads(xml_bytes)pprint.pprint(plist_dict)

So is this a .rtf file? Saving it as a .rtf or .rtfd doesn't work, but then upon searching, I found that RTFDs are a slightly different format of rich text files, and ones that are saved from TextEdit for example, are Mac OS X bundles! (As in they are secretly a folder that the OS hides from you) It seems that Keychain Access.app creates a RTF file for the note text, but you can't really serialize a bundle to bytes, as its a folder with files inside. More searching, and I found the Apple Type Code list, and there is "com.apple.rtfd", but also "com.apple.flat-rtfd", which it says is a "pasteboard" format!

The Pasteboard can be thought of as Mac OS X's 'clipboard', or mechanis of trasnferring data between applications, drag and drop, and more. It seems that Keychain Access.app specifically creates this pasteboard content because of a feature that Keychain Access.app has, the ability to copy the secure note to the clipboard.

So that is how Keychain Access.app stores Secure Notes in the keychain. I thought this was an interesting little reverse engineering experiment. Hope this is useful to someone!