Skip to content
Create a gist now

Instantly share code, notes, and snippets.

Embed URL


Subversion checkout URL

You can clone with
Download ZIP
OS X Lion Password Hash Instructions

Password Hash Accessing:

  • Grab plist file from /var/db/dslocal/nodes/Default/users/username.plist
  • Convert to xml

    plutil -convert xml1 username.plist
  • Grab the ShadowHashData key and base64 decode it (install base64 with port install base64)

    echo "Data from ShadowHashData Key" | base64 -d > ShadowHashData
  • Convert the resultant binary plist file into xml

    plutil -convert xml1 ShadowHashData
  • Grab the SALTED-SHA512 Key and base64 decode it

    echo "Data from SALTED-SHA512 Key" | base64 -d > hashfile

    *Reveal hash:

    xxd -p -c 256 hashfile | cut -c 9-

Opening a user plist from 10.7 and getting the binary-encoded bit

    require 'facter/util/plist'
    users_plist = Plist::parse_xml(`plutil -convert xml1 -o /dev/stdout /var/db/dslocal/nodes/Default/users/brit_xml.plist`)
    password_hash_plist = users_plist['ShadowHashData'][0].string
    IO.popen('plutil -convert xml1 -o - -', mode='r+') do |io|
      io.write password_hash_plist
      @converted_plist =
    converted_hash_plist = Plist::parse_xml(@converted_plist)
    password_hash = converted_hash_plist['SALTED-SHA512'].string.unpack("H*")[0]
    puts password_hash

The problems here are that facter/util/plist cannot handle binary plists - so we need to convert them. Which sucks.

Using CFPropertyList

    require 'cfpropertylist'
    require 'base64'
    newplist = => 'demouser_edit.plist')
    newdata = CFPropertyList.native_types(newplist.value)
    bplist =
    bplistdata = CFPropertyList.native_types(bplist.value)
    password_hash = bplistdata['SALTED-SHA512'].unpack("H*")[0][8..-1]

Nate's Gist -->

user { 'testuser': ensure => 'present', comment => 'Demonstration User', gid => '20', home => '/Users/testuser', password => 'aaa6c1f945132d2599079fe90c9d20e608e607344b86328c1ef8ad8dc820c1bb5a31fd816b8ae546fed6dcf58ff023794f8250a66935d6d0687b737f24aae2ed', shell => '/bin/bash', uid => '1026', }


Can you do it in RubyCocoa without converting the plist with plutil? I can't seem to figure it out.


Updated plist to include revised/updated facter/util/plist method WITHOUT writing a file.

Thanks for the tip. Getting the password is simple, but storing it again is problem. There is a RubyCocoa bug in Lion that generates a Segmentation fault when trying to init an NSData object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.