Sonntag, 18. Oktober 2015

Import 1Password 3 or 4 data to KeepPass


I am a long term user of 1Password, even though I never upgraded from 1Password 3 due to the ridiculous price. So it was time to move to KeePass 2.

Hooray, Password 3 is able to export all entries into a txt file, separated by tabs which should make a nice CSV-File. But hold, the file is encoded ambiguous. For instance, the "note" field is not enclosed in quotation marks and exhibits a mix of escaped and not escaped new lines. The general CSV importer from KeePass is great, but it was not able to resolve this problem.

Next try: moving all data from 1Password 3 to a trial version of 1Password 4, since 1Password 4 claims to be able to export to CSV. And yes, it does - but only for the login entries! All other categories are not exported.

So to be clear: neither 1Password 3 nor 1Password 4 is able to export its complete data in a reasonable format. New users be aware. 

So it's time to pull out some serious tools here.

1. Export from 1Password 4 to 1PIF-File. This is JSON and contains all data.



2. Convert from JSON to well formed CSV using a little python script.
Before running this script, change the filenames. Also note, that only 5 fields are exported: title, username, password, url and note. If you need more, you have to extend the script. Here is the code:
 
# Tested with Python 2.7

import json
from pprint import pprint

 
f = open("E:\\data.test.1pif",'r')
out = open("E:\\1p.csv",'w')

for line in f:
    
    username = ""
    title = ""
    password = ""
    location = ""   
    notes = ""
    
    #-- Skip lines with '***'    
    if line[0:3] == '***':
        continue
 
    #-- Parse line
    data = json.loads(line);       
    #pprint(data);
    
    print "------------------------"
    title = data['title']     
    location = data['location']     
    
    if 'notesPlain' in  data['secureContents']:
        notes = data['secureContents']['notesPlain']

    if 'fields' in data['secureContents']:
        
        for field in  data['secureContents']['fields']:
            if 'designation' in field and field['designation']=='password':
                password = field['value']
            if 'designation' in field and field['designation']=='username':
                username = field['value']
    
    # todo: escape "," 
    notes = notes.replace("\n","\\n")
    
    newline =  title + "," + username + "," + password + "," + location + ",\"" + notes + "\"\n" 
    print(newline)
    out.write(newline.encode('utf-8'))               

f.close()
out.close() 
 
 
3. Import the csv file using the KeePass 2 "General CSV" import filter. 
Just use the default setting, in the third tab you have to change the order of the fields to match the CSV file.