Come Kode salva i tuoi codici
Dove Kode tiene le tue chiavi 2FA, come si sincronizzano e come riportarle fuori.
Solo nel tuo portachiavi
Ogni account, compresa la chiave segreta da cui nascono i codici, è salvato come elemento del portachiavi dell’iPhone, disponibile dopo il primo sblocco. La chiave non finisce mai nel database dell’app, nelle impostazioni, nei file di log, nelle analisi o nei rapporti sugli arresti anomali.
Portachiavi iCloud
Con la sincronizzazione attiva (l’impostazione predefinita) l’elemento è segnato come sincronizzabile, quindi Portachiavi iCloud lo porta sugli altri dispositivi Apple e su un nuovo iPhone. Portachiavi iCloud è cifrato end-to-end. Se disattivi la sincronizzazione, le chiavi restano solo su questo iPhone («solo questo dispositivo») e non passano a un altro telefono.
Nessun server
Kode non si collega mai alla rete. I codici vengono calcolati con lo standard TOTP (RFC 6238) usando HMAC-SHA1/256/512: gli stessi codici di Google Authenticator.
Blocco
Face ID o codice quando apri l’app, e di nuovo dopo un minuto in background. Quando l’app non è attiva, una schermata di blocco copre tutto, così non vedi mai un codice quando passi da un’app all’altra. Un codice copiato sparisce dagli appunti dell’iPhone dopo 60 secondi. Puoi incollarlo sul Mac con Appunti condivisi, dove resta finché non copi qualcos’altro.
Il formato del file di backup
Il backup cifrato è un file JSON. La chiave viene ricavata dalla tua password con PBKDF2-HMAC-SHA256 (600.000 iterazioni, salt di 16 byte), e il contenuto è cifrato con AES-256-GCM. ciphertext è il testo cifrato seguito dal tag GCM di 16 byte. Tutti i campi binari sono in Base64.
{
"format": "kode-backup",
"version": 1,
"kdf": { "name": "PBKDF2-HMAC-SHA256", "iterations": 600000, "salt": "…" },
"cipher": { "name": "AES-256-GCM", "nonce": "…" },
"ciphertext": "…"
}
Una volta decifrato, il contenuto è un elenco di account. Ogni account ha anche un indirizzo otpauth:// già pronto, che la maggior parte delle app sa importare.
{
"created": "2026-09-24T09:41:00Z",
"accounts": [
{
"issuer": "GitHub", "name": "anna", "secret": "JBSWY3DPEHPK3PXP",
"algorithm": "SHA1", "digits": 6, "period": 30,
"uri": "otpauth://totp/GitHub:anna?secret=JBSWY3DPEHPK3PXP&issuer=GitHub&algorithm=SHA1&digits=6&period=30"
}
]
}
Per decifrare il file senza Kode (Python con il pacchetto cryptography):
import base64, getpass, hashlib, json, sys
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
backup = json.load(open(sys.argv[1]))
b64 = base64.b64decode
key = hashlib.pbkdf2_hmac("sha256", getpass.getpass().encode(),
b64(backup["kdf"]["salt"]), backup["kdf"]["iterations"], 32)
plain = AESGCM(key).decrypt(b64(backup["cipher"]["nonce"]), b64(backup["ciphertext"]), None)
for account in json.loads(plain)["accounts"]:
print(account["uri"])