Skip to content

Instantly share code, notes, and snippets.

@gcollazo
Created March 8, 2014 16:35
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save gcollazo/9434580 to your computer and use it in GitHub Desktop.
Save gcollazo/9434580 to your computer and use it in GitHub Desktop.
Python methods to interact with Mac OS X Keychain
import re
import os
def getpassword(service, account):
def decode_hex(s):
s = eval('"' + re.sub(r"(..)", r"\x\1", s) + '"')
if "" in s: s = s[:s.index("")]
return s
cmd = ' '.join([
"/usr/bin/security",
" find-generic-password",
"-g -s '%s' -a '%s'" % (service, account),
"2>&1 >/dev/null"
])
p = os.popen(cmd)
s = p.read()
p.close()
m = re.match(r"password: (?:0x([0-9A-F]+)\s*)?\"(.*)\"$", s)
if m:
hexform, stringform = m.groups()
if hexform:
return decode_hex(hexform)
else:
return stringform
def setpassword(service, account, password):
cmd = 'security add-generic-password -U -a %s -s %s -p %s' % (account, service, password)
p = os.popen(cmd)
s = p.read()
p.close()
@adibendahan
Copy link

Thanks!

@scconroy
Copy link

Not sure if its an addition since this was written, but I've got an option on the "security find-generic-password" command that will display only the password in the output( '-w'), relieving the need for the regex matching on the output from '-g'.

As far as I can see, you can just replace -g with -w and delete the regex operations. Let me know if I'm wrong, though.

Running Sierra 10.12.6

@mrmurphy
Copy link

Fantastic, thanks to all of you

@YusDyr
Copy link

YusDyr commented Oct 24, 2023

Another way is:

import subprocess
def get_password_from_keychain(service, account):
    command = f"/usr/bin/security find-generic-password -s '{service}' -a '{account}' -g -w"
    result = subprocess.run(command, shell=True, capture_output=True)
    password = result.stdout.decode().strip()
    return password

@codeskipper
Copy link

Thanks all.

As I had a dedicated keychain instead of the standard one called 'login', I added that to the example from @YusDyr and omitted the '-g' as it not needed.

import subprocess
def get_password_from_keychain(keychain, service, account):
    command = f"/usr/bin/security find-generic-password -w -s '{service}' -a '{account}' '{keychain}'"
    result = subprocess.run(command, shell=True, capture_output=True)
    password = result.stdout.decode().strip()
    return password

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment