Como descodificar uma cópia encriptada do iPhone Apple iTunes?

fui convidado por uma série de infelizes usuários de iPhone para ajudá-los a restaurar os dados de seus backups iTunes. Isto é fácil quando eles não são criptografados, mas não quando eles são criptografados, se ou não a senha é conhecida.

como tal, estou a tentar descobrir o esquema de encriptação usado nos ficheiros mddata e mdinfo quando encriptados. Eu não tenho problemas em ler esses arquivos de outra forma, e tenho construído algumas bibliotecas C# robustas para fazê-lo. (Se você é capaz de ajudar, eu não me importo que a linguagem que usas. É o princípio que procuro aqui!)

o Apple "iPhone OS Enterprise Deployment Guide" afirma que " as cópias de segurança do dispositivo podem ser armazenadas em formato encriptado, seleccionando o iPhone cifrado Opção de Backup no painel de resumo do dispositivo do iTunes. Os arquivos são criptografados usando AES128 com uma chave de 256 bits. A chave é armazenada de forma segura no chaveiro do iPhone."

É uma boa pista, e há uma boa informação aqui no Stackoverflow no iPhone AES/Rijndael. a interoperabilidade que sugere um tamanho de chave de 128 e modo CBC pode ser utilizada.

Para além de qualquer outro ofuscamento, é necessário um vector de chave e inicialização (IV)/sal.

pode-se assumir que a chave é uma manipulação da "senha de backup" que os usuários são solicitados a entrar pelo iTunes e passado para "AppleMobileBackup.exe ", Acolchoado de uma forma ditada pela CBC. No entanto, dada a referência ao chaveiro do iPhone, eu me pergunto se a "senha de backup" pode não ser usado como senha em um certificado X509 ou chave privada simétrica, e que o certificado ou chave privada em si pode ser usado como a chave. ( AES e o processo de cifragem/descodificação do iTunes é simétrico.)

A IV é outra questão, e podem ser algumas coisas. Talvez seja uma das chaves para o iTunes, ou para os próprios dispositivos.

Embora o comentário da Apple sugira que a chave está presente no porta-chaves do dispositivo, acho que isto ... não é importante? Pode-se restaurar uma cópia de segurança encriptada para um dispositivo diferente, O que sugere que toda a informação relevante para a descodificação está presente na configuração do backup e do iTunes, e que tudo o que estiver apenas no dispositivo é irrelevante e substituível neste contexto. Então, onde está a chave?

listei os caminhos abaixo de uma máquina de janelas, mas é uma grande quantidade, Qualquer que seja o sistema operacional que usemos.

O " \ appdata \ Roaming \ Apple Computer\iTunes\itunesprefs.xml" contém um PList com uma entrada" Keychain " dict nele. O " \programdata\apple \ Lockdown\09037027da8f4bdefdea97d706703ca034c88bab.plist "contains a PList with "DeviceCertificate", "HostCertificate", and "RootCertificate", all of which appear to be valid X509 certs. O mesmo arquivo também parece conter chaves assimétricas "RootPrivateKey" e "HostPrivateKey" (minha leitura sugere que estes podem ser PKCS #7-enveloped). Além disso, dentro de cada cópia de segurança existem valores de" AuthSignature "e" AuthData " na Manifestar.plist file, embora estes parecem ser rodados como cada arquivo é incrementalmente backup, sugeriu que eles não são tão úteis como uma chave, a menos que algo realmente muito envolvido está sendo feito.

Há muitas coisas enganadoras por aí que sugerem que obter dados de backups encriptados é fácil. Não é, e que eu saiba não foi feito. A encriptação de backup é outra questão completamente diferente, e não é o que estou a tentar fazer.

Isto não se trata de cortar o iPhone ou algo assim. Tudo o que procuro aqui é um meio de extrair dados (fotos, contatos, etc.) a partir de cópias de segurança criptografadas do iTunes como eu posso unencrypted ones. Tentei todo o tipo de permutações com a informação que pus lá em cima, mas não consegui nada. Apreciaria quaisquer pensamentos ou técnicas que possa ter perdido.

Author: Community, 2009-09-30

4 answers

Os investigadores de segurança Jean-Baptiste Bédrune e Jean Sigwald para fazer isso at Hack-in-the-box Amsterdam 2011. Desde então, a Apple lançou um papel branco de segurança da iOS. com mais detalhes sobre chaves e algoritmos, e Charlie Miller et al. ter lançou o Manual Do Hacker , que cobre algumas das mesmas ground in a how-to fashion. Quando o iOS 10 saiu pela primeira vez, houve mudanças. para o formato de backup que A Apple não divulgou no início, mas vários as pessoas alteraram o formato com engenharia reversa . As cópias de segurança encriptadas são óptimas. O melhor dos backups de iPhone encriptados é que contêm coisas. como senhas de Wi-Fi que não estão em backups normais não encriptados. Como discutido no [[31]] iOS Security Whitepaper , cópias de segurança encriptadas são considerados mais "seguros", por isso a Apple considera ok incluir mais informações sensíveis neles.

Aviso importante: obviamente, a descodificar a cópia de segurança do dispositivo iOS remove a sua encriptação. Para proteger a sua privacidade e segurança, só executa estes programas numa máquina com encriptação em disco inteiro. enquanto isso é possível para um especialista em segurança escrever software que protege chaves em memória, por exemplo, usando funções como VirtualLock() e SecureZeroMemory() entre muitas outras coisas, estes Os programas em Python Irão guardar as suas chaves de encriptação e senhas em textos para ser lixo recolhido pelo Python. Isto significa as suas chaves e senhas secretas viverão em RAM por um tempo, de onde eles vão vazar para a sua troca arquivo e para o seu disco, onde um adversário pode recuperá-los. Presente derrota completamente o ponto de ter um backup criptografado.

Como descodificar cópias de segurança: em teoria

Opapel branco de segurança do iOS explica os conceitos fundamentais de chaves por ficheiro, classes de protecção, chaves da classe de protecção e teclas de teclado melhor do que posso. Se não estás já familiarizado com isto, toma alguns. debates do Parlamento Europeu

Agora sabes que todos os ficheiros do iOS estão encriptados com os seus próprios ficheiros aleatórios. chave de encriptação por ficheiro, pertence a uma classe de protecção, e o ficheiro por ficheiro as chaves de encriptação são guardadas nos meta-dados do sistema de ficheiros, enroladas na chave da classe de protecção.

Para descodificar:

  1. Descodificar a tecla armazenada na entrada BackupKeyBag de Manifest.plist. Uma visão de alto nível desta estrutura é apresentada em o papel branco . O iPhone Wiki descreve o formato binário: um campo tipo de cadeia de 4 bytes, um 4-byte campo de comprimento Big-endiano, e depois o próprio valor.

    Os valores importantes são as propriedades PBKDF2 ITER e SALT, o dobro sal de protecção DPSL e contagem de iterações DPIC, e depois para cada protecção CLS, a chave embrulhada.

  2. Se usar a senha de salvaguarda, obtém uma chave de 32 bytes usando o PBKDF2 correcto sal e número de iterações. Primeiro utilizar uma ronda SHA256 com DPSL e DPIC, depois uma ronda SHA1 com ITER e SALT.

    Desembrulhar cada tecla embalada de acordo com RFC 3394 .
  3. Descodificar a base de dados do manifesto, retirando a classe de protecção de 4 bytes e a chave mais comprida da ManifestKey em Manifest.plist, e desembrulhando-a. Você agora tem um Base de dados SQLite com todos os meta-dados dos ficheiros.

  4. Para cada ficheiro de interesse, obtém a encriptação por ficheiro encriptado por classe código da chave e da classe de protecção por à procura na base de Dados Files.file coluna para um plano binário que contenha EncryptionKey e ProtectionClass entradas. Remover a marca inicial de quatro bytes de EncryptionKey antes de utilizar.

    Então, obtém a chave final de descodificação desembrulhando-a com a classe chave que foi desembrulhada com a senha de reserva. Em seguida, descriptografar o ficheiro usar o AES no modo CBC com um zero IV.

Como descodificar as cópias de segurança: na prática

No formulário de código-fonte runnable, aqui está como descodificar o Calculadora preferências do ficheiro de uma cópia de segurança cifrada do iPhone:

#!/usr/bin/env python2.7
# coding: UTF-8

import argparse
import base64
import getpass
import hashlib
import os.path
import pprint
import random
import shutil
import sqlite3
import stat
import string
import struct
import sys
import tempfile

import Crypto.Cipher.AES # https://www.dlitz.net/software/pycrypto/
import biplist
import fastpbkdf2

def main():
    ## Parse options
    parser = argparse.ArgumentParser()
    parser.add_argument('--backup-directory', dest='backup_directory',
                      default='data/encrypted')
    parser.add_argument('--password-pipe', dest='password_pipe',
                        help="""\
Keeps password from being visible in system process list.
Typical use: --password-pipe=<(echo -n foo)
""")
    parser.add_argument('--no-anonymize-output', dest='anonymize',
                        action='store_false')
    parser.add_argument('--base64-passcode-key-pipe', dest='passcode_key_pipe',
                        help="""\
Provide a previously derived passcode key to save time doing PBDKF2 when
developing""")
    args = parser.parse_args()
    global ANONYMIZE_OUTPUT
    ANONYMIZE_OUTPUT = args.anonymize
    if ANONYMIZE_OUTPUT:
        print 'Warning: All output keys are FAKE to protect your privacy'

    manifest_file = os.path.join(args.backup_directory, 'Manifest.plist')
    with open(manifest_file, 'rb') as infile:
        manifest_plist = biplist.readPlist(infile)
    keybag = Keybag(manifest_plist['BackupKeyBag'])
    # the actual keys are unknown, but the wrapped keys are known
    keybag.printClassKeys()

    if args.password_pipe:
        password = readpipe(args.password_pipe)
    else:
        password = getpass.getpass('Backup password: ')

    if args.passcode_key_pipe:
        passcode_key = base64.decodestring(readpipe(args.passcode_key_pipe))
    else:
        passcode_key = None

    ## Unlock keybag with password
    if not keybag.unlockWithPasscode(password, passcode_key):
        raise Exception('Could not unlock keybag; bad password?')
    # now the keys are known too
    keybag.printClassKeys()

    ## Decrypt metadata DB
    manifest_key = manifest_plist['ManifestKey'][4:]
    with open(os.path.join(args.backup_directory, 'Manifest.db'), 'r') as db:
        encrypted_db = db.read()

    manifest_class = struct.unpack('<l', manifest_plist['ManifestKey'][:4])[0]
    key = keybag.unwrapKeyForClass(manifest_class, manifest_key)
    decrypted_data = AESdecryptCBC(encrypted_db, key)

    temp_dir = tempfile.mkdtemp()
    try:
        # Does anyone know how to get Python’s SQLite module to open some
        # bytes in memory as a database?
        db_filename = os.path.join(temp_dir, 'db.sqlite3')
        with open(db_filename, 'w') as db_file:
            db_file.write(decrypted_data)
        conn = sqlite3.connect(db_filename)
        c = conn.cursor()
        c.execute("""
            SELECT fileID, domain, relativePath, file
            FROM Files
            WHERE relativePath LIKE '%/Preferences/com.apple.calculator.plist'
            ORDER BY relativePath""")
        results = c.fetchall()
    finally:
        shutil.rmtree(temp_dir)

    for item in results:
        fileID, domain, relativePath, file_bplist = item

        plist = biplist.readPlistFromString(file_bplist)
        file_data = plist['$objects'][plist['$top']['root'].integer]
        size = file_data['Size']

        protection_class = file_data['ProtectionClass']
        encryption_key = plist['$objects'][
            file_data['EncryptionKey'].integer]['NS.data'][4:]

        backup_filename = os.path.join(args.backup_directory,
                                       fileID[:2], fileID)
        with open(backup_filename, 'rb') as infile:
            data = infile.read()
            key = keybag.unwrapKeyForClass(protection_class, encryption_key)
            # truncate to actual length, as encryption may introduce padding
            decrypted_data = AESdecryptCBC(data, key)[:size]

        print '== decrypted data:'
        print wrap(decrypted_data)
        print

        print '== pretty-printed calculator preferences'
        pprint.pprint(biplist.readPlistFromString(decrypted_data))

##
# this section is mostly copied from parts of iphone-dataprotection
# http://code.google.com/p/iphone-dataprotection/

CLASSKEY_TAGS = ["CLAS","WRAP","WPKY", "KTYP", "PBKY"]  #UUID
KEYBAG_TYPES = ["System", "Backup", "Escrow", "OTA (icloud)"]
KEY_TYPES = ["AES", "Curve25519"]
PROTECTION_CLASSES={
    1:"NSFileProtectionComplete",
    2:"NSFileProtectionCompleteUnlessOpen",
    3:"NSFileProtectionCompleteUntilFirstUserAuthentication",
    4:"NSFileProtectionNone",
    5:"NSFileProtectionRecovery?",

    6: "kSecAttrAccessibleWhenUnlocked",
    7: "kSecAttrAccessibleAfterFirstUnlock",
    8: "kSecAttrAccessibleAlways",
    9: "kSecAttrAccessibleWhenUnlockedThisDeviceOnly",
    10: "kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly",
    11: "kSecAttrAccessibleAlwaysThisDeviceOnly"
}
WRAP_DEVICE = 1
WRAP_PASSCODE = 2

class Keybag(object):
    def __init__(self, data):
        self.type = None
        self.uuid = None
        self.wrap = None
        self.deviceKey = None
        self.attrs = {}
        self.classKeys = {}
        self.KeyBagKeys = None #DATASIGN blob
        self.parseBinaryBlob(data)

    def parseBinaryBlob(self, data):
        currentClassKey = None

        for tag, data in loopTLVBlocks(data):
            if len(data) == 4:
                data = struct.unpack(">L", data)[0]
            if tag == "TYPE":
                self.type = data
                if self.type > 3:
                    print "FAIL: keybag type > 3 : %d" % self.type
            elif tag == "UUID" and self.uuid is None:
                self.uuid = data
            elif tag == "WRAP" and self.wrap is None:
                self.wrap = data
            elif tag == "UUID":
                if currentClassKey:
                    self.classKeys[currentClassKey["CLAS"]] = currentClassKey
                currentClassKey = {"UUID": data}
            elif tag in CLASSKEY_TAGS:
                currentClassKey[tag] = data
            else:
                self.attrs[tag] = data
        if currentClassKey:
            self.classKeys[currentClassKey["CLAS"]] = currentClassKey

    def unlockWithPasscode(self, passcode, passcode_key=None):
        if passcode_key is None:
            passcode1 = fastpbkdf2.pbkdf2_hmac('sha256', passcode,
                                            self.attrs["DPSL"],
                                            self.attrs["DPIC"], 32)
            passcode_key = fastpbkdf2.pbkdf2_hmac('sha1', passcode1,
                                                self.attrs["SALT"],
                                                self.attrs["ITER"], 32)
        print '== Passcode key'
        print base64.encodestring(anonymize(passcode_key))
        for classkey in self.classKeys.values():
            if not classkey.has_key("WPKY"):
                continue
            k = classkey["WPKY"]
            if classkey["WRAP"] & WRAP_PASSCODE:
                k = AESUnwrap(passcode_key, classkey["WPKY"])
                if not k:
                    return False
                classkey["KEY"] = k
        return True

    def unwrapKeyForClass(self, protection_class, persistent_key):
        ck = self.classKeys[protection_class]["KEY"]
        if len(persistent_key) != 0x28:
            raise Exception("Invalid key length")
        return AESUnwrap(ck, persistent_key)

    def printClassKeys(self):
        print "== Keybag"
        print "Keybag type: %s keybag (%d)" % (KEYBAG_TYPES[self.type], self.type)
        print "Keybag version: %d" % self.attrs["VERS"]
        print "Keybag UUID: %s" % anonymize(self.uuid.encode("hex"))
        print "-"*209
        print "".join(["Class".ljust(53),
                      "WRAP".ljust(5),
                      "Type".ljust(11),
                      "Key".ljust(65),
                      "WPKY".ljust(65),
                      "Public key"])
        print "-"*208
        for k, ck in self.classKeys.items():
            if k == 6: print ""
            print "".join(
                [PROTECTION_CLASSES.get(k).ljust(53),
                 str(ck.get("WRAP","")).ljust(5),
                 KEY_TYPES[ck.get("KTYP",0)].ljust(11),
                 anonymize(ck.get("KEY", "").encode("hex")).ljust(65),
                 anonymize(ck.get("WPKY", "").encode("hex")).ljust(65),
                 ck.get("PBKY", "").encode("hex")])
        print

def loopTLVBlocks(blob):
    i = 0
    while i + 8 <= len(blob):
        tag = blob[i:i+4]
        length = struct.unpack(">L",blob[i+4:i+8])[0]
        data = blob[i+8:i+8+length]
        yield (tag,data)
        i += 8 + length

def unpack64bit(s):
    return struct.unpack(">Q",s)[0]
def pack64bit(s):
    return struct.pack(">Q",s)

def AESUnwrap(kek, wrapped):
    C = []
    for i in xrange(len(wrapped)/8):
        C.append(unpack64bit(wrapped[i*8:i*8+8]))
    n = len(C) - 1
    R = [0] * (n+1)
    A = C[0]

    for i in xrange(1,n+1):
        R[i] = C[i]

    for j in reversed(xrange(0,6)):
        for i in reversed(xrange(1,n+1)):
            todec = pack64bit(A ^ (n*j+i))
            todec += pack64bit(R[i])
            B = Crypto.Cipher.AES.new(kek).decrypt(todec)
            A = unpack64bit(B[:8])
            R[i] = unpack64bit(B[8:])

    if A != 0xa6a6a6a6a6a6a6a6:
        return None
    res = "".join(map(pack64bit, R[1:]))
    return res

ZEROIV = "\x00"*16
def AESdecryptCBC(data, key, iv=ZEROIV, padding=False):
    if len(data) % 16:
        print "AESdecryptCBC: data length not /16, truncating"
        data = data[0:(len(data)/16) * 16]
    data = Crypto.Cipher.AES.new(key, Crypto.Cipher.AES.MODE_CBC, iv).decrypt(data)
    if padding:
        return removePadding(16, data)
    return data

##
# here are some utility functions, one making sure I don’t leak my
# secret keys when posting the output on Stack Exchange

anon_random = random.Random(0)
memo = {}
def anonymize(s):
    global anon_random, memo
    if ANONYMIZE_OUTPUT:
        if s in memo:
            return memo[s]
        possible_alphabets = [
            string.digits,
            string.digits + 'abcdef',
            string.letters,
            "".join(chr(x) for x in range(0, 256)),
        ]
        for a in possible_alphabets:
            if all(c in a for c in s):
                alphabet = a
                break
        ret = "".join([anon_random.choice(alphabet) for i in range(len(s))])
        memo[s] = ret
        return ret
    else:
        return s

def wrap(s, width=78):
    "Return a width-wrapped repr(s)-like string without breaking on \’s"
    s = repr(s)
    quote = s[0]
    s = s[1:-1]
    ret = []
    while len(s):
        i = s.rfind('\\', 0, width)
        if i <= width - 4: # "\x??" is four characters
            i = width
        ret.append(s[:i])
        s = s[i:]
    return '\n'.join("%s%s%s" % (quote, line ,quote) for line in ret)

def readpipe(path):
    if stat.S_ISFIFO(os.stat(path).st_mode):
        with open(path, 'rb') as pipe:
            return pipe.read()
    else:
        raise Exception("Not a pipe: {!r}".format(path))

if __name__ == '__main__':
    main()

Que imprime esta saída:

Warning: All output keys are FAKE to protect your privacy
== Keybag
Keybag type: Backup keybag (1)
Keybag version: 3
Keybag UUID: dc6486c479e84c94efce4bea7169ef7d
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Class                                                WRAP Type       Key                                                              WPKY                                                             Public key
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
NSFileProtectionComplete                             2    AES                                                                         4c80b6da07d35d393fc7158e18b8d8f9979694329a71ceedee86b4cde9f97afec197ad3b13c5d12b
NSFileProtectionCompleteUnlessOpen                   2    AES                                                                         09e8a0a9965f00f213ce06143a52801f35bde2af0ad54972769845d480b5043f545fa9b66a0353a6
NSFileProtectionCompleteUntilFirstUserAuthentication 2    AES                                                                         e966b6a0742878ce747cec3fa1bf6a53b0d811ad4f1d6147cd28a5d400a8ffe0bbabea5839025cb5
NSFileProtectionNone                                 2    AES                                                                         902f46847302816561e7df57b64beea6fa11b0068779a65f4c651dbe7a1630f323682ff26ae7e577
NSFileProtectionRecovery?                            3    AES                                                                         a3935fed024cd9bc11d0300d522af8e89accfbe389d7c69dca02841df46c0a24d0067dba2f696072

kSecAttrAccessibleWhenUnlocked                       2    AES                                                                         09a1856c7e97a51a9c2ecedac8c3c7c7c10e7efa931decb64169ee61cb07a0efb115050fd1e33af1
kSecAttrAccessibleAfterFirstUnlock                   2    AES                                                                         0509d215f2f574efa2f192efc53c460201168b26a175f066b5347fc48bc76c637e27a730b904ca82
kSecAttrAccessibleAlways                             2    AES                                                                         b7ac3c4f1e04896144ce90c4583e26489a86a6cc45a2b692a5767b5a04b0907e081daba009fdbb3c
kSecAttrAccessibleWhenUnlockedThisDeviceOnly         3    AES                                                                         417526e67b82e7c6c633f9063120a299b84e57a8ffee97b34020a2caf6e751ec5750053833ab4d45
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly     3    AES                                                                         b0e17b0cf7111c6e716cd0272de5684834798431c1b34bab8d1a1b5aba3d38a3a42c859026f81ccc
kSecAttrAccessibleAlwaysThisDeviceOnly               3    AES                                                                         9b3bdc59ae1d85703aa7f75d49bdc600bf57ba4a458b20a003a10f6e36525fb6648ba70e6602d8b2

== Passcode key
VNfSPwXOK8mvKxTtmZ51JppAzrsG7gkWSiY8W7xnRX4=

== Keybag
Keybag type: Backup keybag (1)
Keybag version: 3
Keybag UUID: dc6486c479e84c94efce4bea7169ef7d
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Class                                                WRAP Type       Key                                                              WPKY                                                             Public key
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
NSFileProtectionComplete                             2    AES        64e8fc94a7b670b0a9c4a385ff395fe9ba5ee5b0d9f5a5c9f0202ef7fdcb386f 4c80b6da07d35d393fc7158e18b8d8f9979694329a71ceedee86b4cde9f97afec197ad3b13c5d12b
NSFileProtectionCompleteUnlessOpen                   2    AES        22a218c9c446fbf88f3ccdc2ae95f869c308faaa7b3e4fe17b78cbf2eeaf4ec9 09e8a0a9965f00f213ce06143a52801f35bde2af0ad54972769845d480b5043f545fa9b66a0353a6
NSFileProtectionCompleteUntilFirstUserAuthentication 2    AES        1004c6ca6e07d2b507809503180edf5efc4a9640227ac0d08baf5918d34b44ef e966b6a0742878ce747cec3fa1bf6a53b0d811ad4f1d6147cd28a5d400a8ffe0bbabea5839025cb5
NSFileProtectionNone                                 2    AES        2e809a0cd1a73725a788d5d1657d8fd150b0e360460cb5d105eca9c60c365152 902f46847302816561e7df57b64beea6fa11b0068779a65f4c651dbe7a1630f323682ff26ae7e577
NSFileProtectionRecovery?                            3    AES        9a078d710dcd4a1d5f70ea4062822ea3e9f7ea034233e7e290e06cf0d80c19ca a3935fed024cd9bc11d0300d522af8e89accfbe389d7c69dca02841df46c0a24d0067dba2f696072

kSecAttrAccessibleWhenUnlocked                       2    AES        606e5328816af66736a69dfe5097305cf1e0b06d6eb92569f48e5acac3f294a4 09a1856c7e97a51a9c2ecedac8c3c7c7c10e7efa931decb64169ee61cb07a0efb115050fd1e33af1
kSecAttrAccessibleAfterFirstUnlock                   2    AES        6a4b5292661bac882338d5ebb51fd6de585befb4ef5f8ffda209be8ba3af1b96 0509d215f2f574efa2f192efc53c460201168b26a175f066b5347fc48bc76c637e27a730b904ca82
kSecAttrAccessibleAlways                             2    AES        c0ed717947ce8d1de2dde893b6026e9ee1958771d7a7282dd2116f84312c2dd2 b7ac3c4f1e04896144ce90c4583e26489a86a6cc45a2b692a5767b5a04b0907e081daba009fdbb3c
kSecAttrAccessibleWhenUnlockedThisDeviceOnly         3    AES        80d8c7be8d5103d437f8519356c3eb7e562c687a5e656cfd747532f71668ff99 417526e67b82e7c6c633f9063120a299b84e57a8ffee97b34020a2caf6e751ec5750053833ab4d45
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly     3    AES        a875a15e3ff901351c5306019e3b30ed123e6c66c949bdaa91fb4b9a69a3811e b0e17b0cf7111c6e716cd0272de5684834798431c1b34bab8d1a1b5aba3d38a3a42c859026f81ccc
kSecAttrAccessibleAlwaysThisDeviceOnly               3    AES        1e7756695d337e0b06c764734a9ef8148af20dcc7a636ccfea8b2eb96a9e9373 9b3bdc59ae1d85703aa7f75d49bdc600bf57ba4a458b20a003a10f6e36525fb6648ba70e6602d8b2

== decrypted data:
'bplist00\xd3\x01\x02\x03\x04\x05\x06\\DisplayValue[MemoryValue_\x10\x14Trigono'
'metricModeKey_\x10%3.14159265358979323846264338327950288_\x10#2.71828182845904'
'5235360287471352662\x08\x08\x0f\x1c(?g\x8d\x00\x00\x00\x00\x00\x00\x01\x01\x00'
'\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
'\x00\x00\x00\x8e'

== pretty-printed calculator preferences
{'DisplayValue': '3.14159265358979323846264338327950288',
 'MemoryValue': '2.718281828459045235360287471352662',
 'TrigonometricModeKey': False}

Crédito Extra

O iPhone-código de protecção de Dados publicado por Bédrune e Sigwald can descodificar o chaveiro de uma cópia de segurança, incluindo coisas divertidas como o wifi gravado e senhas do sítio web:

$ python iphone-dataprotection/python_scripts/keychain_tool.py ...

--------------------------------------------------------------------------------------
|                              Passwords                                             |
--------------------------------------------------------------------------------------
|Service           |Account          |Data           |Access group  |Protection class|
--------------------------------------------------------------------------------------
|AirPort           |Ed’s Coffee Shop |<3FrenchRoast  |apple         |AfterFirstUnlock|
...
Esse código já não funciona em backups de telefones usando os últimos iOS, mas ... nem tudo mudou ... deixe um comentário se gostarias que eu o fizesse. actualize o código acima para enviar também as senhas gravadas; P
 84
Author: andrewdotn, 2017-10-22 19:13:28

Desculpa, mas pode até ser mais complicado, envolvendo pbkdf2, ou mesmo uma variação dele. Ouça a sessão da WWDC 2010 # 209, que fala principalmente sobre as medidas de segurança no iOS 4, mas também menciona brevemente a criptografia separada de backups e como eles estão relacionados.

Podes ter a certeza que sem saber a password, não há maneira de a decifrares, nem mesmo pela Força bruta.

Vamos supor que quer tentar habilitar as pessoas que sabem a senha a vai buscar os dados das cópias de segurança. Receio que não haja maneira de ver o código real no iTunes para descobrir quais são os algos Empregados.

De volta aos dias de Newton, eu tinha que descriptografar dados de um programa e era capaz de chamar sua função de decriptação diretamente (conhecendo a senha, é claro) sem a necessidade de mesmo undersand seu algoritmo. Já não é assim tão fácil, infelizmente.

Tenho a certeza de que há pessoas habilidosas por aí que podem fazer engenharia reversa disso. código iTunes-você só tem que deixá-los interessados. Em teoria, o algos da Apple deve ser concebido de forma a tornar os dados ainda seguros (isto é, praticamente inquebráveis por métodos de Força bruta) para qualquer atacante, sabendo o método de encriptação EXACTO. E na sessão 209 da WWDC, eles entraram em detalhes sobre o que eles fazem para conseguir isso. Talvez consiga respostas directamente da equipa de segurança da Apple se lhes disser as suas boas intenções. Afinal, até eles devem saber essa segurança por ofuscação não é realmente eficiente. Tenta a lista de correio de segurança. Mesmo que não repondam, talvez outra pessoa silenciosamente na lista irá responder com alguma ajuda. Boa sorte!
 5
Author: Thomas Tempelmann, 2010-09-26 18:09:42
Ainda não tentei, mas a Elcomsoft lançou um produto que afirmam ser capaz de descodificar cópias de segurança, para fins forenses. Talvez não tão fixe como a engenharia de uma solução, mas pode ser mais rápido.

Http://www.elcomsoft.com/eppb.html

 1
Author: Jablair, 2010-09-24 13:21:36
 -3
Author: Nathan de Vries, 2009-10-01 13:13:04