Schlüsselanhänger exportieren

Um auf ein Ubutun zu migrieren, möchte ich mein gesamtes Passwort exportieren, beispielsweise in eine CSV-Datei.

In der Schlüsselbundverwaltung habe ich das Exportmenü gefunden, aber es ist immer deaktiviert, auch wenn der Zugriff entsperrt ist.

Was soll ich machen?

Siehe auch diese Frage/Antwort: apple.stackexchange.com/a/185980/129823
Für iCloud-Elemente im Schlüsselbund: apple.stackexchange.com/a/408952/151764

Antworten (9)

So ungefähr habe ich es vor vielen Jahren gemacht, das ist das Skript-Update für Yosemite 10.11.5 - aber ich habe es nicht getestet.

  1. Ein Skript, das jedes Element im Schlüsselbund als Text speichert:

    security dump-keychain -d login.keychain > keychain.txt
    
  2. Ein zweites AppleScript-Element, das auf die Schaltfläche "Zulassen" klickt, die das erste Skript auslöst, wenn das Element aus dem KeyChain gelesen wird.

[Bearbeiten: Juli 2016] Dies wurde auf 10.11.5 aktualisiert. Beachten Sie, dass einige berichtet haben, dass sie ihren Mac mit der Verzögerung von 0,2 gesperrt haben. Ich habe das Skript darauf beschränkt, nur 200 Ergebnisse gleichzeitig zu verarbeiten, wenn Sie also 1050 Schlüsselbundelemente haben , müssen Sie dieses Skript 6 Mal im ScriptEditor ausführen, Sie müssen auch zulassen, dass der ScriptEditor im Abschnitt Barrierefreiheit in den Sicherheitseinstellungen in aktiviert wird:

tell application "System Events"
    set maxAttemptsToClick to 200
    repeat while exists (processes where name is "SecurityAgent")
        if maxAttemptsToClick = 0 then exit repeat
        set maxAttemptsToClick to maxAttemptsToClick - 1
        tell process "SecurityAgent"
            try
                click button 2 of window 1
            on error
                keystroke " "
            end try
        end tell
        delay 0.2
    end repeat
end tell

Dann hat der obige Link / Yosemite-Update auch einen Ruby-Konvertierungsschritt von der Textdatei in CSV. Viel Glück!

ShreevatsaR weist in den Kommentaren darauf hin, dass diese Ruby-Konvertierung nur "Internetpasswörter" und nicht "Anwendungspasswörter" abdeckt. Dies liegt daran, dass das Ziel des Skripts darin besteht, die "Internet-Passwörter" in die Anwendung zu exportieren 1Password.

Und hier ist eine Stapelüberlauf - Frage und -Antwort in die gleiche Richtung

Das System.keychain ist hier:

security dump-keychain -d /Library/Keychains/System.keychain > systemkeychain.txt

Damit AppleScript mit dem Dialogfeld interagieren kann, muss in den Systemeinstellungen -> Sicherheits- und Datenschutzeinstellungen -> Registerkarte „Datenschutz“ in der Option „Eingabehilfen“ „Script Editor.app“ aktiviert seinSystemeinstellungen -> Sicherheits- und Datenschutzeinstellungen -> Registerkarte „Datenschutz“, Barrierefreiheitsoption hervorgehoben

Vielen Dank! Es funktioniert gut. Ich weiß nur nicht, warum ich meine System.keychain nicht exportieren kann. Aber die meisten Schlüsselanhänger gibt es auch auf login.keychain.
Siehe Update für diesen Schlüsselbund-Elementpfad, aber es könnte nach Benutzername und Passwort für jedes Element fragen, was möglicherweise das Allow-Skript sein kann, um es bereitzustellen.
Denkt. Ich habe keine Kompetenz in AppleScript. Ich habe nur wenige Passwörter in diesem Schlüsselbund, also werde ich mein Hauptpasswort viele Male eingeben.
Wenn Sie keine Ausgabe erhalten, versuchen Sie, den Befehl im selben Verzeichnis wie den Schlüsselbund auszuführen.
@ShreevatsaR Es gibt 20 Gabeln dieses Ruby-Skripts. Wenn Sie eine finden, die Ihr Problem behebt, würden Sie entweder hier kommentieren oder meine Antwort bearbeiten, um den neuen Link hinzuzufügen? Viel Glück.
@MichaelStoner: Tatsächlich wurde mir später klar, dass das Hauptproblem darin besteht, dass das Ruby-Skript nur Dinge vom Typ "Internetpasswort" erhielt, nicht die "Anwendungspasswörter" ... Ich hatte nur wenige davon und kopierte sie manuell aus dem keychain.txt (die sie hatte). Daher habe ich keine Varianten des Ruby-Skripts untersucht.
Das AppleScript funktionierte bei mir nicht unter OS X 10.10.3 Yosemite und behauptete „Systemereignisse haben einen Fehler: Gruppe 1 von Fenster 1 des Prozesses „SecurityAgent“ kann nicht abgerufen werden. Ungültiger Index“.
Könnte jemand das Skript so aktualisieren, dass es auf Yosemite und auch für den Systemschlüsselbund funktioniert, bei dem Sie Benutzername und Passwort für jedes Element eingeben müssen?
@oarfish gist.github.com/TaergLee/50934395f0dafbb7f7cb TaergLess scheint dies getan zu haben, aber ich habe weder den gesamten Code ausgeführt noch gelesen.
@MarcelWaldvogel aktualisiertes Skript behoben "Systemereignisse haben einen Fehler ..." sollte jetzt funktionieren, machen Sie sowohl Ihren Weg als auch die Aktualisierung des Index
Weiß jemand wo man die findet Local Items? Sie scheinen keine zugehörige .keychainDatei zu haben.
Diese Antwort funktioniert nicht auf Mojave. Das Apple-Skript macht die Benutzeroberfläche im Grunde nur unbrauchbar, hilft aber nicht beim Dialog, der auch ein Passwort erfordert.

Ich habe ein Python-Skript geschrieben, das den Schlüsselbund-Dump in eine Excel-Datei konvertiert, und dachte, ich teile es mit Ihnen. Ich wähle Excel gegenüber CSV oder TSV, weil viele Leute es installiert haben und es einfach funktioniert, indem man auf die Datei doppelklickt. Sie können das Skript natürlich ändern, um jedes andere Format zu drucken. Ich habe dies unter OS X 10.11 El Capitan gemacht, sollte aber auch unter älteren Betriebssystemen funktionieren.

  1. Da ich meine Passwörter nicht gerne im Klartext auf meiner Festplatte speichere, habe ich mit der Festplattendienstprogramm-App einen verschlüsselten Container erstellt. Öffnen Sie einfach das Festplatten-Dienstprogramm (drücken Sie cmd+ Space, geben Sie „Disk“ ein). cmdIn der App + für neues Bild drücken N, den Namen auf SEC ändern, die Verschlüsselung auf 256-Bit AES ändern und unter SEC in einem Verzeichnis Ihrer Wahl speichern. Mounten Sie dann das Volume, indem Sie auf die Datei doppelklicken (oder das Festplattendienstprogramm verwenden).

  2. Erstellen Sie eine neue Datei namens keychain.py im sicheren Container und fügen Sie den folgenden Code ein.

  3. Öffnen Sie nun Terminal.app und wechseln Sie in das gemountete verschlüsselte Volume:cd /Volumes/SEC

  4. Für die Installation des Excel-Moduls benötigen wir den Python-Paketmanager (Sie werden nach Ihrem Passwort gefragt):sudo easy_install pip

  5. Wir müssen das Python-Excel-Modul installieren:sudo pip install xlwt

  6. Exportieren Sie nun die Passwörter mit einer der anderen Antworten auf diese Frage. Ich habe es gerade getan security dump-keychain -d > keychain.txtund Spam auf die Schaltfläche Zulassen geklickt, während ich die Maus mit meiner anderen Hand gedrückt hielt.

  7. Der letzte Schritt besteht darin, die txt-Datei mit dem Python-Skript in eine lesbare Excel-Tabelle zu konvertieren:python keychain.py keychain.txt keychain.xls

.

#!/usr/bin/env python

import sys
import os
import re
import xlwt

# Regex to match both generic and internet passwords from a keychain dump
regex = re.compile(
    r"""
    keychain:\s"(?P<kchn>[^"]+)"\n                  # absolute path and file of keychain
    version:\s(\d\d\d)\n                            # version
    class:\s"(?P<clss>(genp|inet))"\n               # generic password or internet password
    attributes:\n
    (\s*?0x00000007\s<blob>=(?P<name>[^\n]+)\n)?    # name
    (\s*?0x00000008\s<blob>=(?P<hex8>[^\n]+)\n)?    # ? only used at certificates
    (\s*?"acct"<blob>=(?P<acct>[^\n]+)\n)?          # account
    (\s*?"atyp"<blob>=(?P<atyp>[^\n]+)\n)?          # account type ("form"), sometimes int
    (\s*?"cdat"<timedate>=[^"]*(?P<cdat>[^\n]+)\n)? # datetime created
    (\s*?"crtr"<uint32>=(?P<crtr>[^\n]+)\n)?        # vendor key with four chars like "aapl"
    (\s*?"cusi"<sint32>=(?P<cusi>[^\n]+)\n)?        # ? always null
    (\s*?"desc"<blob>=(?P<desc>[^\n]+)\n)?          # description
    (\s*?"gena"<blob>=(?P<gena>[^\n]+)\n)?          # ? always null except one rare cases
    (\s*?"icmt"<blob>=(?P<icmt>[^\n]+)\n)?          # ? some sort of description
    (\s*?"invi"<sint32>=(?P<invi>[^\n]+)\n)?        # ? always null
    (\s*?"mdat"<timedate>=[^"]*(?P<mdat>[^\n]+)\n)? # datetime last modified
    (\s*?"nega"<sint32>=(?P<nega>[^\n]+)\n)?        # ? always null
    (\s*?"path"<blob>=(?P<path>[^\n]+)\n)?          # path
    (\s*?"port"<uint32>=(?P<port>[^\n]+)\n)?        # port number in hex
    (\s*?"prot"<blob>=(?P<prot>[^\n]+)\n)?          # ? always null
    (\s*?"ptcl"<uint32>=(?P<ptcl>[^\n]+)\n)?        # protocol but is blob ("http", "https")
    (\s*?"scrp"<sint32>=(?P<scrp>[^\n]+)\n)?        # ? always null except one rare cases
    (\s*?"sdmn"<blob>=(?P<sdmn>[^\n]+)\n)?          # used for htaccess AuthName
    (\s*?"srvr"<blob>=(?P<srvr>[^\n]+)\n)?          # server
    (\s*?"svce"<blob>=(?P<svce>[^\n]+)\n)?          # ? some sort of description
    (\s*?"type"<uint32>=(?P<type>[^\n]+)\n)?        # some blob: "iprf", "note"
    data:\n
    "(?P<data>[^"]*)"                               # password
    """, re.MULTILINE | re.VERBOSE)

# Dictionary used by the clean function (Apple is not always right about the
# types of the field)
field2type = { 
    "name": "blob",
    "hex8": "blob",
    "acct": "blob",
    "atyp": "simple",
    "cdat": "timedate",
    "crtr": "uint32",
    "cusi": "sint32",
    "desc": "blob", 
    "gena": "blob",
    "icmt": "blob",
    "invi": "sint32",
    "mdat": "timedate",
    "nega": "sint32",
    "path": "blob",
    "port": "uint32",
    "prot": "blob",
    "ptcl": "blob",
    "scrp": "sint32",
    "sdmn": "blob",
    "srvr": "blob", 
    "svce": "blob",
    "type": "blob",
    "data": "simple",
    "kchn": "simple",
    "clss": "simple"
}

def clean(field, match):
    value = match.group(field)
    if not value or value == "<NULL>":
        # print null values as empty strings
        return ""
    if field2type[field] == "blob":
        # strip " at beginning and end
        return value[1:-1]
    elif field2type[field] == "timedate":
        # convert timedate to the iso standard
        value = value[1:-1]
        return value[0:4] + "-" + value[4:6] + "-" + value[6:8] + "T" + \
            value[8:10] + ":" + value[10:12] + ":" + value[12:14] + "Z" + value[16:19]
    elif field2type[field] == "uint32":
        # if it really is a hex int, convert it to decimal
        value = value.strip()
        if re.match("^0x[0-9a-fA-F]+$", value):
            return int(value, 16)
        else:
            return value
    else:
        # do nothing, just print it as it is
        return value

def print_help():
    print "Usage: python keychain.py INPUTFILE OUTPUTFILE"
    print "Example: python keychain.py keychain.txt keychain.xls"
    print "  where keychain.txt was created by `security dump-keychain -d > keychain.txt`"
    print "  When dumping the keychain, you have to click 'Allow' for each entry in your"
    print "  keychain. Position you mouse over the button and go clicking like crazy."




print "Keychain 0.1: convert an Apple Keychain dump to an Excel (XLS) spreadsheet."

# Check for correct parameters
if len(sys.argv) != 3:
    print_help()
    sys.exit(1)
elif len(sys.argv) == 3:
    if not os.path.isfile(sys.argv[1]):
        print "Error: no such file '{0}'".format(sys.argv[1])
        print_help()
        exit(1)

# Read keychain file
buffer = open(sys.argv[1], "r").read()
print "Read {0} bytes from '{1}'".format(len(buffer), sys.argv[1])

# Create excel workbook and header
wb = xlwt.Workbook()
ws = wb.add_sheet("Keychain")
ws.write(0, 0, "Name")
ws.write(0, 1, "Account")
ws.write(0, 2, "Password")
ws.write(0, 3, "Protocol")
ws.write(0, 4, "Server")
ws.write(0, 5, "Port")
ws.write(0, 6, "Path")
ws.write(0, 7, "Description")
ws.write(0, 8, "Created")
ws.write(0, 9, "Modified")
ws.write(0, 10, "AuthName")
ws.write(0, 11, "AccountType")
ws.write(0, 12, "Type")
ws.write(0, 13, "Keychain")

# Find passwords and add them to the excel spreadsheet
i = 1
for match in regex.finditer(buffer):
    ws.write(i, 0, clean("name", match))
    ws.write(i, 1, clean("acct", match))
    ws.write(i, 2, clean("data", match))
    ws.write(i, 3, clean("ptcl", match))
    ws.write(i, 4, clean("srvr", match))
    ws.write(i, 5, clean("port", match))
    ws.write(i, 6, clean("path", match))
    ws.write(i, 7, clean("desc", match))
    ws.write(i, 8, clean("cdat", match))
    ws.write(i, 9, clean("mdat", match))
    ws.write(i, 10, clean("sdmn", match))
    ws.write(i, 11, clean("atyp", match))
    ws.write(i, 12, clean("clss", match))
    ws.write(i, 13, clean("kchn", match))
    i += 1
wb.save(sys.argv[2])

print "Saved {0} passwords to '{1}'".format(i-1, sys.argv[2])
Wow, das sieht wirklich gründlich aus. Ich werde es versuchen, obwohl ich noch eine Lösung für die sicheren Notizen und App-Passwörter brauche ... :( Dies sollte mich jedoch weit bringen.
Fand diese hervorragende Aufschlüsselung sicherer Notizen: stackoverflow.com/questions/22370552/…
Jetzt muss ich nur noch herausfinden, wie man einen RTFD-Export erstellt, der ein eingebettetes Bild enthält. Ich habe ein paar Notizen mit Passwörtern in Bildschirmkappen.
Tolle Ergänzung dazu, plus eins und danke

Ab OSX 10.10.3 gibt es eine neue Möglichkeit zum automatischen Akzeptieren (ich bin während eines Upgrade-Pfads auf Probleme gestoßen).

Bash-Funktionen (zu entweder .profileoder .bash_rcDateien hinzugefügt)

## At the terminal when you start getting the prompts, type `Accepts` and press enter
function Accepts () {
osascript <<EOF
  tell application "System Events"
    repeat while exists (processes where name is "SecurityAgent")
      tell process "SecurityAgent" to click button "Allow" of window 1
      delay 0.2
    end repeat
  end tell
EOF
}

## At the terminal when you start getting the prompts, type `Accepts YourUsername YourPassword` and press enter
function AcceptWithCreds () {
username="$1"
password="$2"

[ -z "${password}" ] && return 1

osascript 2>/dev/null <<EOF
    set appName to "${username}"
    set appPass to "${password}"
    tell application "System Events"
        repeat while exists (processes where name is "SecurityAgent")
            tell process "SecurityAgent"
                if exists (text field 1 of window 1) then
                    set value of text field 1 of window 1 to appName
                    set value of text field 2 of window 1 to appPass
                end if
            end tell
      tell process "SecurityAgent" to click button "Allow" of window 1
            delay 0.2
        end repeat
    end tell
EOF
echo 'Finished...'
}

Und verwenden Sie dieses Skript, um Ihren Schlüsselbund zu sichern ( sudo ./dump.sh)

#!/bin/bash
# Run above script in another window

security dump-keychain -d login.keychain > keychain-login.txt
security dump-keychain -d /Library/Keychains/System.keychain > keychain-system.txt
Das ist toll! Als ich es ausführte, kam ich execution error: System Events got an error: osascript is not allowed assistive access.auf die Befehlszeile. Der einfachste Weg, damit umzugehen, bestand darin, den AppleScript-Code in die Script Editor-App einzufügen und von dort aus auszuführen.
AppleScripts funktionieren nicht unter 10.10.5
Dies funktionierte für mich unter OS X El Capitan 10.11.6. Achten Sie darauf, nicht das letzte Zeichen (Backtick) aus dem Skript zu kopieren. Der osascript is not allowed assistive accessFehler kann vermieden werden, indem Sie Ihre Terminal-App in Systemeinstellungen => Sicherheit & Datenschutz => Eingabehilfen zulassen.
Auf Mojave funktioniert das nicht. AcceptWithCreds wird einfach beendet, ohne etwas zu tun.

Die Antwort von @MichaelStoner ist ein guter Anfang, schlägt jedoch unter OS X 10.10.3 Yosemite mit seinem AppleScript-Code fehl System Events got an error: Can’t get group 1 of window 1 of process "SecurityAgent". Invalid index.

Nachdem ich ein wenig herumgespielt hatte, funktionierte die folgende Lösung für mich:

tell application "System Events"
    repeat while exists (processes where name is "SecurityAgent")
        tell process "SecurityAgent"
            keystroke " "
        end tell
        delay 1
    end repeat
end tell

Nach dem Start müssen Sie auf den Dialog "Erlauben" klicken. Dieser Code wird eine Weile dauern, aber ich rate davon ab, die Verzögerung zu verringern ("Verzögerung 0,2" hat dazu geführt, dass ich meinen Mac zwangsweise ausschalte). Holen Sie sich einfach eine Tasse Kaffee.

Das Leerzeichen -> Tastendruck " " funktioniert nur, wenn Sie Systemeinstellungen -> Tastatureinstellungen -> Registerkarte "Kurzbefehle", untere Option "Vollzugriff auf die Tastatur" und dann "Alle Steuerelemente" ausgewählt haben.

Die Schlüsselbund-Exportfunktion gilt für ARTIKEL, nicht für den gesamten Schlüsselbund. Außerdem können Sie die meisten Artikel nicht exportieren – dann sehen Sie die ausgegraute Exportfunktion.

Verwenden Sie die Migrationsassistent- App , um den Schlüsselbund von einem Mac auf einen anderen zu kopieren .

Oder tun Sie es manuell, indem Sie die Schlüsselkettendatei kopieren, die sich im Ordner ~/Library/Keychains/ befindet.

Öffnen Sie die Schlüsselbundverwaltungs- App auf einem neuen Computer und wählen Sie File> Add Keychain….

danke, aber ich sagte "zu einem anderen Betriebssystem" ... ich möchte OS X verlassen ...
Danke für die Bearbeitung und Klarheit. Das andere Betriebssystem war irreführend. Sie möchten es also als Textdatei (CSV)?
Ja, eine CSV-Datei, während alles in Ordnung ist ...

Die securityBinärdatei ruft Elemente aus dem Schlüsselbund über die Befehlszeile ab, sodass Sie dies in Python skripten können, um den Inhalt systematisch auszugeben. Es hängt wirklich davon ab, in welchem ​​Format Sie die Daten haben möchten und wie Sie sie in Zukunft verwenden werden.

Kopieren / Einfügen ist auch eine anständige Option, wenn Sie wissen, wie lange Sie daran interessiert sind, eine neue Lösung zu implementieren, und ob Sie ein vorhandenes Programm oder eine vorhandene Bibliothek lernen / suchen müssen, die den Inhalt in das von Ihnen gewählte Format ausgibt.

Das Menü „Exportelemente“ ist für den Export öffentlicher und/oder privater Schlüssel vorgesehen, für die es branchenübliche Dateiformate gibt, um die Daten entsprechend zu codieren und zu schützen, wenn sie zum Austausch und Transport im Dateisystem gespeichert werden. Diese Funktion ist in der Hilfe zum Schlüsselbundassistenten kurz dokumentiert.

Es gibt keinen anderen Weg, als es zu scripten? Ok, ich werde mir diese Binärdatei ansehen, aber ... so viele Grundbedürfnisse, nur um so etwas wie eine CSV zu haben ...
Wenn Sie Ihren Beitrag bearbeiten können, um anzugeben, welches neue Betriebssystem und welches cvs-Format Ihnen gefällt, hätte ich möglicherweise weitere Ideen für Sie. Wie gesagt, sehr vage...

Es gibt ein Tool namens KeychaindumpPro https://hackforums.net/showthread.php?tid=5803486 .

Zum Extrahieren von Passphrase/Konto/Zahlung/Secure Note/PublicKey/PrivateKey/SymmetricKey/Certificate usw. aus dem Schlüsselbund im Stillen.

Sie sollten keine Links einfügen, die erfordern, dass ein Benutzer ein Konto erstellt, um Inhalte anzuzeigen. Es wäre besser, wenn Sie den Inhalt des Links anders formulieren würden.

Das Python-Skript ist großartig. Ich habe es ein wenig modifiziert, um eine CSV-Datei für den Firefox-Import zu erstellen. Auf MacOs braucht es vorher einen pip pinstall pandas

#!/usr/bin/env python

import sys
import os
import re
import csv

import pandas as pd
#from time
import datetime


# Regex to match both generic and internet passwords from a keychain dump
regex = re.compile(
    r"""
    keychain:\s"(?P<kchn>[^"]+)"\n                  # absolute path and file of keychain
    version:\s(\d\d\d)\n                            # version
    class:\s"(?P<clss>(genp|inet))"\n               # generic password or internet password
    attributes:\n
    (\s*?0x00000007\s<blob>=(?P<name>[^\n]+)\n)?    # name
    (\s*?0x00000008\s<blob>=(?P<hex8>[^\n]+)\n)?    # ? only used at certificates
    (\s*?"acct"<blob>=(?P<acct>[^\n]+)\n)?          # account
    (\s*?"atyp"<blob>=(?P<atyp>[^\n]+)\n)?          # account type ("form"), sometimes int
    (\s*?"cdat"<timedate>=[^"]*(?P<cdat>[^\n]+)\n)? # datetime created
    (\s*?"crtr"<uint32>=(?P<crtr>[^\n]+)\n)?        # vendor key with four chars like "aapl"
    (\s*?"cusi"<sint32>=(?P<cusi>[^\n]+)\n)?        # ? always null
    (\s*?"desc"<blob>=(?P<desc>[^\n]+)\n)?          # description
    (\s*?"gena"<blob>=(?P<gena>[^\n]+)\n)?          # ? always null except one rare cases
    (\s*?"icmt"<blob>=(?P<icmt>[^\n]+)\n)?          # ? some sort of description
    (\s*?"invi"<sint32>=(?P<invi>[^\n]+)\n)?        # ? always null
    (\s*?"mdat"<timedate>=[^"]*(?P<mdat>[^\n]+)\n)? # datetime last modified
    (\s*?"nega"<sint32>=(?P<nega>[^\n]+)\n)?        # ? always null
    (\s*?"path"<blob>=(?P<path>[^\n]+)\n)?          # path
    (\s*?"port"<uint32>=(?P<port>[^\n]+)\n)?        # port number in hex
    (\s*?"prot"<blob>=(?P<prot>[^\n]+)\n)?          # ? always null
    (\s*?"ptcl"<uint32>=(?P<ptcl>[^\n]+)\n)?        # protocol but is blob ("http", "https")
    (\s*?"scrp"<sint32>=(?P<scrp>[^\n]+)\n)?        # ? always null except one rare cases
    (\s*?"sdmn"<blob>=(?P<sdmn>[^\n]+)\n)?          # used for htaccess AuthName
    (\s*?"srvr"<blob>=(?P<srvr>[^\n]+)\n)?          # server
    (\s*?"svce"<blob>=(?P<svce>[^\n]+)\n)?          # ? some sort of description
    (\s*?"type"<uint32>=(?P<type>[^\n]+)\n)?        # some blob: "iprf", "note"
    data:\n
    "(?P<data>.*)"                               # password
    """, re.MULTILINE | re.VERBOSE)

# Dictionary used by the clean function (Apple is not always right about the
# types of the field)
field2type = { 
    "name": "blob",
    "hex8": "blob",
    "acct": "blob",
    "atyp": "simple",
    "cdat": "timedate",
    "crtr": "uint32",
    "cusi": "sint32",
    "desc": "blob", 
    "gena": "blob",
    "icmt": "blob",
    "invi": "sint32",
    "mdat": "timedate",
    "nega": "sint32",
    "path": "blob",
    "port": "uint32",
    "prot": "blob",
    "ptcl": "blob",
    "scrp": "sint32",
    "sdmn": "blob",
    "srvr": "blob", 
    "svce": "blob",
    "type": "blob",
    "data": "simple",
    "kchn": "simple",
    "clss": "simple"
}

def clean(field, match):
    value = match.group(field)
    if not value or value == "<NULL>":
        # print null values as empty strings
        return ""
    if field2type[field] == "blob":
        # strip " at beginning and end
        return value[1:-1]
    elif field2type[field] == "timedate":
        # convert timedate to the iso standard
        value = value[1:-1]
        return value[0:4] + "-" + value[4:6] + "-" + value[6:8] + "T" + \
            value[8:10] + ":" + value[10:12] + ":" + value[12:14] + "Z" + value[16:19]
    elif field2type[field] == "uint32":
        # if it really is a hex int, convert it to decimal
        value = value.strip()
        if re.match("^0x[0-9a-fA-F]+$", value):
            return int(value, 16)
        else:
            return value
    else:
        # do nothing, just print it as it is
        return value

def print_help():
    print "Usage: python keychain4ff.py INPUTFILE OUTPUTFILE"
    print "Example: python keychain.py keychain.txt keychain.xls"
    print "  where keychain.txt was created by `security dump-keychain -d > keychain.txt`"
    print "  When dumping the keychain, you have to click 'Allow' for each entry in your"
    print "  keychain. Position you mouse over the button and go clicking like crazy."



print "Keychain 0.1: convert an Apple Keychain dump to a .csv for Firefox import ."

# Check for correct parameters
if len(sys.argv) != 3:
    print_help()
    sys.exit(1)
elif len(sys.argv) == 3:
    if not os.path.isfile(sys.argv[1]):
        print "Error: no such file '{0}'".format(sys.argv[1])
        print_help()
        exit(1)

# Read keychain file
buffer = open(sys.argv[1], "r").read()
print "Read {0} bytes from '{1}'".format(len(buffer), sys.argv[1])


df = pd.DataFrame( columns = ["url", "username", "password", "httpRealm", "formActionOrigin", "guid", "timeCreated", "timeLastUsed", "timePasswordChanged", ])

# Find passwords and add them to the Data Frame
i = 0
for match in regex.finditer(buffer):
    url = clean("ptcl", match)
    if len(url):
        if url == 'htps':
            url = 'https'
        elif url == 'http':
            pass
        else:
            continue
            
        datstr = clean("cdat", match)
        mo = re.match(r"(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z000", datstr)
        if mo:
            dstr = mo.group(1)+" "+mo.group(2)+" "+mo.group(3)+" "+mo.group(4)+" "+mo.group(5)+" "+mo.group(6)
            epoch = int( (datetime.datetime(int(mo.group(1)), int(mo.group(2)), int(mo.group(3)), int(mo.group(4)), int(mo.group(5)), int(mo.group(6))) - datetime.datetime(1970,1,1) ).total_seconds())
            
        record = {"url": url + "://"+ clean("srvr", match),
                  "username" : clean("acct", match),
                  "password" : clean("data", match),
                  "httpRealm": "",
                  "formActionOrigin": url + "://"+ clean("srvr", match), 
                  "guid": "",
                  "timeCreated":         epoch,
                  "timeLastUsed":        epoch,
                  "timePasswordChanged": epoch,
        }
        df = df.append(record, ignore_index=True)
        i += 1
df.to_csv(sys.argv[2], index=False, quotechar='"', quoting=csv.QUOTE_ALL, escapechar="\\")

print "Saved {0} passwords to '{1}'".format(i-1, sys.argv[2])

Schlüsseltresor

Keysafe liest und entschlüsselt Apple-Schlüsselbunddateien. Verwenden Sie Keysafe, um ohne Mac sicher auf Ihre Passwörter und Zugangsdaten zuzugreifen.

Ich habe ein Tool namens Keysafe geschrieben, um den Inhalt von Schlüsselbunddateien zu extrahieren.

Keysafe ist nicht kostenlos; eine Lizenz ist erforderlich, um einen Schlüsselbund vollständig zu entschlüsseln. Ohne Lizenz werden die Inhalte immer noch extrahiert, aber die entschlüsselten Werte werden teilweise redigiert und sichere Notizen werden nicht in RTFD-Dateien nachbearbeitet.

Wenn Sie einen Schlüsselbund haben, der nicht mit Keysafe "einfach funktioniert", wenden Sie sich bitte an uns. Das Schlüsselbundformat ist umfangreich und es ist immer interessant, Randfälle zu finden.