Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Exporting (iCloud) Keychain and Safari credentials to a CSV file

Exporting (iCloud) Keychain and Safari credentials to a CSV file

After my dad died, I wanted to be able to have access any of his online accounts going forward. My dad was a Safari user and used iCloud Keychain to sync his credentials across his devices. I don’t want to have to keep an OS X user account around just to access his accounts, so I wanted to export his credentials to a portable file.

This is the process I used to create a CSV file of his credentials in the format “example.com,user,pass”. This portable format would be pretty easy to import into 1Password or Safari in the future.

The way I went about this isn’t great; it opens up more opportunities for apps to control one’s Mac through Accessibility APIs, it writes plaintext passwords to disk, and it could use some cleaning up. A better approach might leverage the security command line tool that ships with OS X. That said, I found this method to be a fun illustration of what’s possible using AppleScript (or JavaScript!) and UI scripting on OS X.

Copy the iCloud Keychain into a local Keychain

One’s iCloud Keychain is stored on disk in a different format than a traditional keychain. To access the credentials, I first created a traditional keychain with the iCloud Keychain’s contents. To do this, I clicked File > New Keychain (⌥⌘N) in Keychain Access. In my case, I saved the new keychain to the desktop. I clicked on iCloud in the sidebar, selected all of the passwords, and copied them. I selected the new keychain I just created and pasted the passwords.

Screenshot of Keychain Access asking for the "Local Items" keychain password

Keychain Access prompted me for the “Local Items” keychain password for every password I was pasting. In my case, this would have been over 200 times!

Automating typing the keychain password and clicking “OK”

I ran the following script to take care of this:

-- Taken from a comment by Mr. X on http://selfsuperinit.com/2014/01/20/exporting-icloud-keychain-passwords-as-a-plain-text-file/
set keychainPassword to "keychain password"

tell application "System Events"
    repeat while exists (processes where name is "SecurityAgent")
        tell process "SecurityAgent"
            set value of text field 1 of window 1 to keychainPassword
            click button "OK" of window 1
        end tell
        delay 0.2
    end repeat
end tell

Whatever process is running this script (Script Editor or a standalone bundle), it’ll need permission to “control your computer”.

Screenshot Security & Privacy > Privacy > Accessibility

After that runs, the recently-created local keychain should contain all of the passwords stored in iCloud Keychain.

Write all of the passwords from the keychain to a file

I grabbed a copy of Daniel Jalkut’s “Usable Keychain Scripting” utility to help with the next part, but someone more sane might turn to security.

I ran the following script to write the passwords out to disk:

set the logFile to ((path to desktop) as string) & "Passwords"
set keychainPath to "/Users/Dad/Desktop/dad.keychain"

-- write_to_file taken from http://www.macosxautomation.com/applescript/sbrt/sbrt-09.html
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

tell application "Usable Keychain Scripting"
    set keychainItems to get every keychain item of keychain keychainPath
    repeat with keychainItem in keychainItems
        set aServer to server in keychainItem
        set anAccount to account in keychainItem
        set aPassword to password in keychainItem

        set csvEntry to aServer & "," & anAccount & "," & aPassword & "
"

        my write_to_file(csvEntry, logFile, true)
    end repeat
end tell

There’s a lot that can be improved with this code. For instance, I could have used a consistent naming style between copied and non-copied code. If I took the time to look up an array or list "join" routine, the intent of the could could have been better communicated.

Here again, OS X’s Keychain wanted to do its job, prompting me to allow access for each of the 200+ items.

-- Taken from a comment by Mr. X on http://selfsuperinit.com/2014/01/20/exporting-icloud-keychain-passwords-as-a-plain-text-file/
tell application "System Events"
    repeat while exists (processes where name is "SecurityAgent")
        tell process "SecurityAgent"
            click button "Allow" of window 1
        end tell
        delay 0.2
    end repeat
end tell

After that, I had my file. Inelegant, but it got the job done, and I had fun.

Hi Ricky,
May I ask how did you find the value of the "Local Items" password?
Thanks!

Thanks! It worked quite nicely :D

This doesn't work for me, I get the following error:


keychain.sh: line 1: syntax error near unexpected token `('
keychain.sh: line 1: `set the logFile to ((path to desktop) as string) & "Passwords"'

Any way to fix this? This is for OS X 10.11.5

Thanks.

Works beautifully - even for Yosemite. Thanks!

Did anyone get this to work in Sierra ?

scarlac commented Dec 17, 2016

@AlexandreCassagne Yes, I got it working in Sierra, specifically version 10.12.2 (16C67).

For me, I got a lot of "duplicate" error prompts so I wrapped the security prompts in a try-on-error block like this:

-- Taken from a comment by Mr. X on http://selfsuperinit.com/2014/01/20/exporting-icloud-keychain-passwords-as-a-plain-text-file/
set keychainPassword to "secret"

tell application "System Events"
	repeat while exists (processes where name is "SecurityAgent")
		tell process "SecurityAgent"
			try -- added
				set value of text field 1 of window 1 to keychainPassword
				click button "OK" of window 1
			on error -- added
				-- do nothing and skip -- added
			end try -- added
		end tell
		delay 0.2
	end repeat
end tell

And I also did it for the final export where I got some other errors:

tell application "System Events"
	repeat while exists (processes where name is "SecurityAgent")
		try -- added
			tell process "SecurityAgent"
				click button "Allow" of window 1
			end tell
		on error -- added
			-- ignore it -- added
		end try -- added
		delay 0.2
	end repeat
end tell

Please ensure that you have a comment in the "on error" block, or else the Script Editor will optimize it out. Also, in case anybody is wondering, the "Usable Keychain Secripting" app just runs invisibly in the background. I couldn't tell it was working but the script ran just fine so, yeah.

Fall711 commented Feb 19, 2017

Hi,

I want to leave Apple and my Macbook Pro and i simply want to export all my stored passwords...

I didn't manage to get this script working and i'm really bored of Apple things...

I feel like i can't control my own data because Apple decided to do as they want to...

Can someone help me ?

Thank you.

raywang13 commented Mar 22, 2017 edited

I get this error on set keychainItems to get every **keychain** item of keychain keychainPath on the keyword **keychain**

error: Expected class name but found identifier.

Is anyone else getting this error? I'm running this in ScriptEditor.

someone more sane might turn to security.

I may be the one: https://github.com/lifepillar/CSVKeychain

:)

IgorVoiT commented Jul 4, 2017

Work's nice in sierra 👍

I receive the following error message in macOS High Sierra 10.13 Beta (17A291m):

error "System Events got an error: Can’t get window 1 of process \"SecurityAgent\". Invalid index." number -1719 from window 1 of process "SecurityAgent"

Same problem as @geoffmyers -- However I'm running OS X 10.12.4

Additionally, if I manually enter my iCloud password I get:

"An error has occurred, unable to add an item to the current keychain"

screen shot 2017-07-14 at 2 57 13 pm

if you get an error when you're exporting your "iCloud passwords" it means your iCloud keychain is still enabled. Disable iCloud keychain in system preferences -> iCloud and elect to "save all items" and then all the iCloud password items will move to "login items" in keychain access.. and then you shouldn't have an issue from there

I'm having the same problem as @geoffmyers. Any fix for this yet?

It turns out that the security dialog really wants your content. I fixed it by removing the delays, adding a "try" wrapper, and then sitting there and moving the window little bit. As soon as I did that, it was able to find the window and enter it. Much faster.

set keychainPassword to "keychain password"

tell application "System Events"
	repeat while exists (processes where name is "SecurityAgent")
		try
			tell process "SecurityAgent" to set frontmost to true
			tell process "SecurityAgent"
				set frontmost to true
				
				set value of text field 1 of window 1 to keychainPassword
				click button "OK" of window 1
			end tell
		end try
	end repeat
end tell
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment