Skip to content

Instantly share code, notes, and snippets.

@farialima
Last active November 2, 2021 15:33
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save farialima/25c6d5cb9a6ab62e69e19e635a3e9e3a to your computer and use it in GitHub Desktop.
Exporting "Local Items" Keychain passwords to a CSV file (and Secure Notes each to one file), in one step

Exporting "Local Items" Keychain passwords to a CSV file (and Secure Notes each to one file), in one step

The problem

Apple does not make it easy to export your keychain. In old versions of MacOS, it's possible to "Export" items one-by-one (from the File => Export menu of the Keychain Access app). There is also an easy library to manipulate Key chain app, called "Usable Keychain Scripting". It works like a charm on any version of MacOS, for login keychains. There is also a command-line, security, that lets you manipulate it.

So it is somewhat possible to automate exporting passwords, although you may get a the "Security Dialog" for each of item - thus you may need a little applescript to automate it (taken originally from this site, but it's now down: the snippet can be found in many places, such as here. ).

Furthermore, it's easy to transfer the complete "login" keychain files (files ~/Library/Keychain/*.keychain-db) to a new computer, or drive: you simply copy them, and using the keychain password, you can open them in the Keychain Access app.

BUT in recent versions of MacOS (probably ~2018), the passwords are stored in the "Local Items" keychain, and it uses a different format: the keychain files are in a subfolder of ~/Library/Keychain/, with a unique 32-character hex name. The name of the files are now always keychain-2.db (each in a subfolder, with other files that I couldn't find any documatation about).

These files have some complex security: they cannot be transfered to a new mac, and cannot be exported using the Keychain Access app, nor any other method beside heavy use of AppleScript. They are linked (I don't know how !) to the hardware, and to the disk: for example, if you move your hard drive to a new computer, and boot with this old drive, you will not be able to open the Local Items keychain.

The only way that Apple lets you transfer them is with iCloud... but it's very complex and for my part I haven't been able to do that, I had errors along the way. There are multiple passwords involved, and it's easy to get lost, it seems, and/or not to be able to access them.

This gist proposes a way to export these items iCloud/"Local Items" keychain passwords, with a two-step process: first move the items to a "normal" login keychain, and then exporting this "normal" keychain to a CSV file. The second step uses "Usable Keychain Access". However, in my case, my keychain was so screwed up (I had ported it from many, many versions of MacOS, and many, many Mac Books !) that it didn't work. So I wrote my own script...

My one-step solution

Here, I'm proposing an Applescript (to run in Script Editor) to do it in one step, by simply reading the items from the UI. It's a little tricky to run: you must have opened the keychain (have the list of items visible) in the Keychain Access app, and the cursor positionned on the first one: the script will simply go down one after the other in the list: it'll open the dialog, click the "Show password" checkbox, enter your password, read all the data in the dialog (including password) and save them to the CSV file. It can go wrong, in particular sometimes Keychain may ask you for your password twice, so you may need to edit to duplicate the tell process "SecurityAgent" block to run it twice. It may be better to run by hand a few times, also.

I've been running it Catalina, but I'm quite sur it's working for earlier MacOS. I'd be happy someone can try it on Big Sur or Monterey, and report if it works.


set the myFile to ((path to desktop) as string) & "passwords.csv"
set myPassword to "YOUR PASSWORD"

# function to write to file... very usual
on write_to_file(this_data, target_file, append_data)
	try
		set the target_file to the target_file as string
		set the open_target_file to open for access file target_file with write permission
		if append_data is false then set eof of the open_target_file to 0
		write this_data to the open_target_file starting at eof
		close access the open_target_file
		return true
	on error
		try
			close access file target_file
		end try
		return false
	end try
end write_to_file

# nice headers for the CSV file
my write_to_file("kind, account, site name, where, password
", myFile, true)

repeat while true
	activate application "Keychain Access"
	tell application "System Events"
		# hit the "enter" key to open the dialog for this keychain item
		key code 36 
		tell process "Keychain Access"
			# keep the name of the window to find it later
			set window_name to name of window 1
			# click the "Show password" checkbox
			set theCheckbox to checkbox "Show password:" of tab group 1 of window 1
			tell theCheckbox
				click theCheckbox
			end tell
			delay 0.5
		end tell
		# Enter my password in the security dialog
		# Sometimes, setting the password is needed twice: just duplicated this block for that
		tell process "SecurityAgent"
			set frontmost to true
			keystroke myPassword
			delay 0.2
			keystroke return
		end tell
		delay 1
		# Collect all the data from the keychain item dialog
		tell process "Keychain Access" to tell tab group 1 of window window_name
			set site_name to value of text field 4
			set site_kind to value of text field 2
			set account to value of text field 3
			set site_name to value of text field 4
			try
				# it's not there for SafariCreditCardEntries, not sure where it is
				set site_where to value of text field 5
			on error
				set site_where to "FIELD NOT FOUND"
			end try
			set site_password to value of text field 1
		end tell
		# save them in one line in the CSV file
		my write_to_file(site_kind & "," & account & "," & site_name & "," & site_where & "," & site_password & "
", myFile, true)
		# close the keychain item dialog for this item
		keystroke "w" using command down
		# move down one step in the list
		key code 125
	end tell
	
end repeat

Note that it's a little primitive: it'll never finish and will run forever on the last line !! You'll have to stop it by hand, somehow. Also, for some reason, it takes several seconds at each step... Be patient ! This is really designed to be run once :)

Bonus: script to extract the "Secure Notes" into files

I needed that also, so I wrote it... same mechanism, scraping the UI.

It'll create a text file for each of the security notes.

set the myFolder to ((path to desktop) as string)
set myPassword to "YOUR PASSWORD"

on write_to_file(this_data, target_file, append_data)
	try
		set the target_file to the target_file as string
		set the open_target_file to open for access file target_file with write permission
		if append_data is false then set eof of the open_target_file to 0
		write this_data to the open_target_file starting at eof
		close access the open_target_file
		return true
	on error
		try
			close access file target_file
		end try
		return false
	end try
end write_to_file

repeat while true
	activate application "Keychain Access"
	tell application "System Events"
		key code 36 # "enter" to open the dialog
		tell process "Keychain Access"
			set window_name to name of window 1
			set theCheckbox to checkbox "Show note" of tab group 1 of window 1
			tell theCheckbox
				click theCheckbox
			end tell
			delay 0.5
		end tell
		tell process "SecurityAgent"
			set frontmost to true
			keystroke myPassword
			delay 0.2
			keystroke return
		end tell
		delay 1
		# If the password request appears twice, then first run in once by hand. Then it should only appear once. 	
		# At worse, duplicated the section above
		
		tell process "Keychain Access" to tell tab group 1 of window window_name
			set theNote to value of text area 1 of scroll area 1
		end tell
		my write_to_file(theNote, myFolder & window_name, false)
		keystroke "w" using command down # close dialog
		delay 1
		key code 125 # down arrow
	end tell
	
end repeat
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment