28 votes

Exporter les porte-clés

Pour migrer vers un Ubutun, je voudrais exporter tous mes mots de passe, par exemple vers un fichier CSV.

Dans Keychain Access, j'ai trouvé le menu d'exportation, mais il est toujours désactivé, même lorsque l'accès est déverrouillé.

Que dois-je faire ?

0 votes

Voir aussi cette question/réponse : apple.stackexchange.com/a/185980/129823

1 votes

Pour les éléments iCloud dans le trousseau de clés : apple.stackexchange.com/a/408952/151764

1voto

Oskar Points 1242

Le binaire sécurité récupérera des éléments du trousseau de clés à partir de la ligne de commande, vous pourriez donc le scripter en python pour décharger le contenu de manière systématique. Cela dépend vraiment du format dans lequel vous voulez les données et de la manière dont vous les utiliserez à l'avenir.

La copie / collage est également une option décente si vous savez combien de temps vous devez mettre en œuvre une nouvelle solution et si vous devez apprendre / rechercher un programme ou une bibliothèque existante qui déchargera le contenu dans le format de votre choix.

Le menu d'exportation des éléments est destiné à l'exportation de clés publiques et/ou privées pour lesquelles il existe des formats de fichiers standard de l'industrie pour encoder et protéger les données de manière appropriée lorsqu'elles sont stockées sur le système de fichiers pour l'échange et le transport. Cette fonction est brièvement documentée dans l'aide de l'Assistant trousseau de clés.

0 votes

Il n'y a pas d'autre moyen que de le scripter ? D'accord, je vais regarder ce binaire, mais... un tel besoin basique, juste pour avoir quelque chose comme un CSV ...

1 votes

Si vous pouvez modifier votre message pour spécifier quel nouveau système d'exploitation et que le cvs est un format que vous aimez, j'aurais peut-être quelques idées supplémentaires pour vous. Tel que demandé, c'est très vague...

0voto

unknown Points 1

Il existe un outil appelé KeychaindumpPro https://hackforums.net/showthread.php?tid=5803486.

Pour extraire le mot de passe/compte/paiement/note sécurisée/clé publique/clé privée/clé symétrique/certificat, etc., à partir du trousseau de l'utilisateur en silence.

3 votes

Vous ne devriez pas insérer de liens qui nécessitent à un utilisateur de créer un compte pour voir le contenu. Il serait préférable que vous reformuliez le contenu du lien.

0voto

Martin Huch Points 1

Le script python est génial. Je l'ai un peu modifié pour créer un fichier csv pour l'importation dans Firefox. Sur MacOs, il faut un pip pinstall pandas avant

#!/usr/bin/env python

import sys
import os
import re
import csv

import pandas as pd
#de time
import datetime

# Regex pour faire correspondre les mots de passe génériques et Internet à partir d'une sauvegarde de trousseau
regex = re.compile(
    r"""
    keychain:\s"(?P[^"]+)"\n                  # chemin absolu et fichier du trousseau
    version:\s(\d\d\d)\n                            # version
    class:\s"(?P(genp|inet))"\n               # mot de passe générique ou mot de passe Internet
    attributes:\n
    (\s*?0x00000007\s=(?P[^\n]+)\n)?    # nom
    (\s*?0x00000008\s=(?P[^\n]+)\n)?    # ? utilisé uniquement pour les certificats
    (\s*?"acct"=(?P[^\n]+)\n)?          # compte
    (\s*?"atyp"=(?P[^\n]+)\n)?          # type de compte ("form"), parfois entier
    (\s*?"cdat"=[^"]*(?P[^\n]+)\n)? # date et heure de création
    (\s*?"crtr"=(?P[^\n]+)\n)?        # clé du fournisseur avec quatre caractères comme "aapl"
    (\s*?"cusi"=(?P[^\n]+)\n)?        # ? toujours nulle
    (\s*?"desc"=(?P[^\n]+)\n)?          # description
    (\s*?"gena"=(?P[^\n]+)\n)?          # ? toujours nulle sauf dans certains cas rares
    (\s*?"icmt"=(?P[^\n]+)\n)?          # ? une sorte de description
    (\s*?"invi"=(?P[^\n]+)\n)?        # ? toujours nulle
    (\s*?"mdat"=[^"]*(?P[^\n]+)\n)? # date et heure de dernière modification
    (\s*?"nega"=(?P[^\n]+)\n)?        # ? toujours nulle
    (\s*?"path"=(?P[^\n]+)\n)?          # chemin
    (\s*?"port"=(?P[^\n]+)\n)?        # numéro de port en hexadécimal
    (\s*?"prot"=(?P[^\n]+)\n)?          # ? toujours nulle
    (\s*?"ptcl"=(?P[^\n]+)\n)?        # protocole mais est un blob ("http", "https")
    (\s*?"scrp"=(?P[^\n]+)\n)?        # ? toujours nulle sauf dans certains cas rares
    (\s*?"sdmn"=(?P[^\n]+)\n)?          # utilisé pour AuthName de htaccess
    (\s*?"srvr"=(?P[^\n]+)\n)?          # serveur
    (\s*?"svce"=(?P[^\n]+)\n)?          # ? une sorte de description
    (\s*?"type"=(?P[^\n]+)\n)?        # un blob: "iprf", "note"
    data:\n
    "(?P.*)"                               # mot de passe
    """, re.MULTILINE | re.VERBOSE)

# Dictionnaire utilisé par la fonction de nettoyage (Apple n'a pas toujours raison sur les
# types des champs)
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 == "":
        # affiche les valeurs nulles comme des chaînes vides
        return ""
    if field2type[field] == "blob":
        # supprime le "au début et à la fin
        return value[1:-1]
    elif field2type[field] == "timedate":
        # convertit une date et une heure en norme ISO
        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":
        # si c'est vraiment un entier hexadécimal, le convertir en décimal
        value = value.strip()
        if re.match("^0x[0-9a-fA-F]+$", value):
            return int(value, 16)
        else:
            return value
    else:
        # ne rien faire, simplement l'imprimer tel qu'il est
        return value

def print_help():
    print "Utilisation: python keychain4ff.py INPUTFILE OUTPUTFILE"
    print "Exemple: python keychain.py keychain.txt keychain.xls"
    print "  où keychain.txt a été créé par `security dump-keychain -d > keychain.txt`"
    print "  Lors de la sauvegarde du trousseau, vous devez cliquer sur 'Autoriser' pour chaque entrée dans votre"
    print "  trousseau. Positionnez votre souris sur le bouton et cliquez frénétiquement."

print "Trousseau 0.1: convertir une sauvegarde de trousseau Apple en un fichier .csv pour l'importation dans Firefox."

# Vérifier les paramètres corrects
if len(sys.argv) != 3:
    print_help()
    sys.exit(1)
elif len(sys.argv) == 3:
    if not os.path.isfile(sys.argv[1]):
        print "Erreur: fichier '{0}' introuvable".format(sys.argv[1])
        print_help()
        exit(1)

# Lire le fichier de trousseau
buffer = open(sys.argv[1], "r").read()
print "Lire {0} octets depuis '{1}'".format(len(buffer), sys.argv[1])

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

# Trouver les mots de passe et les ajouter au 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 "Enregistré {0} mots de passe dans '{1}'".format(i-1, sys.argv[2])

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X