Converting on OSX Keychain into Text Notes

The purpose of this notebook is to export the secured notes from an Apple keychain into separate files. It is pretty rough, but generally this only needs to be done once (at least for me this was the case) so no need to polish

IMPORTANT NOTICE: Using an iPython Notebook in a browser is not particularly secure. The decrypted data migth end up in the browser cache. Use Private Browsing mode or clear the cache when you are finished

Note: path is where the keychain lives and where the notes will be written. It should be an encrypted volume.


In [1]:
path = '/Volumes/---/keychains'

In [1]:
#!ls -l $path

retrieve the titles of all notes, and read them into the array list_of_notes


In [7]:
!security dump $path/test.keychain | grep svce > $path/raw_list_of_notes.txt

In [8]:
with open(path+"/raw_list_of_notes.txt") as f:
    content = f.readlines()
#content

In [9]:
import re
def f(txt):
    m = re.match('.*=\"(.*)\"', txt)
    return m.groups()[0]

list_of_notes = list(map (f, content))
#list_of_notes

now retrieve the text of the notes; we make some very crude regex matching on the raw output here


In [47]:
def note_text(name):
    text = !security find-generic-password -g -s "$name" 
    m = re.match(".*<key>NOTE</key>.*?<string>(.*)</string>", text[0])
    if m == None: 
        m = re.match('.*"(.*)"', text[0])
        if m == None: 
            return (name, "-not accessible-")
    return (name, m.groups()[0])

def note_text_raw(name):
    text = !security find-generic-password -g -s "$name" 
    return (name, text)

In [50]:
note_contents = list(map(note_text, list_of_notes))

In [11]:
#note_contents

In [12]:
import pickle
if False:
    output = open(path+'/note_contents.pkl', 'wb')
    pickle.dump(note_contents, output)
    output.close()

In [13]:
if False:
    pkl_file = open(path+'/note_contents.pkl', 'rb')
    note_contents1 = pickle.load(pkl_file)
    pkl_file.close()

In [14]:
#note_contents1

In [60]:
for n in note_contents1:
    if n[1] != "-not accessible-":
        fn = path+'/out/'+n[0].replace("/", "-")+".note"
        output = open(fn, 'w')
        text = n[1].replace('\\012', '\n')
        output.write(text)
        output.close()