Kode

Zo bewaart Kode je codes

Waar Kode je 2FA-sleutels bewaart, hoe ze worden gesynchroniseerd en hoe je ze er weer uit krijgt.

Alleen in je sleutelhanger

Elk account, ook de geheime sleutel waaruit de codes worden berekend, wordt als één item in de sleutelhanger van je iPhone bewaard, beschikbaar na de eerste keer ontgrendelen. De sleutel komt nooit in de database van de app, in instellingen, in logbestanden, in analytics of in crashrapporten.

iCloud-sleutelhanger

Met synchroniseren aan (de standaard) is het item gemarkeerd als synchroniseerbaar, zodat iCloud-sleutelhanger het meeneemt naar je andere Apple-apparaten en naar een nieuwe iPhone. iCloud-sleutelhanger is end-to-end versleuteld. Zet je synchroniseren uit, dan staan de sleutels alleen nog op deze iPhone (“alleen dit apparaat”) en gaan ze niet mee naar een andere telefoon.

Geen server

Kode maakt geen verbinding met internet. De codes worden berekend volgens de TOTP-standaard (RFC 6238) met HMAC-SHA1/256/512: dezelfde codes als in Google Authenticator.

Vergrendeling

Face ID of toegangscode als de app opent, en opnieuw na een minuut op de achtergrond. Zolang de app niet actief is, ligt er een vergrendelscherm over alles, zodat de appkiezer nooit een code laat zien. Een gekopieerde code verdwijnt na 60 seconden van het klembord van je iPhone. Via Universeel klembord kun je hem op je Mac plakken; daar blijft hij staan tot je iets anders kopieert.

Het formaat van het back-upbestand

De versleutelde back-up is een JSON-bestand. De sleutel wordt met PBKDF2-HMAC-SHA256 (600.000 rondes, salt van 16 bytes) uit je wachtwoord afgeleid, en de inhoud wordt versleuteld met AES-256-GCM. ciphertext is de versleutelde tekst, gevolgd door de GCM-tag van 16 bytes. Alle binaire velden zijn Base64.

{
  "format": "kode-backup",
  "version": 1,
  "kdf": { "name": "PBKDF2-HMAC-SHA256", "iterations": 600000, "salt": "…" },
  "cipher": { "name": "AES-256-GCM", "nonce": "…" },
  "ciphertext": "…"
}

Ontsleuteld is de inhoud een lijst met accounts. Elk account heeft ook een kant-en-klaar otpauth://-adres dat de meeste apps kunnen importeren.

{
  "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"
    }
  ]
}

Zo ontsleutel je het bestand zonder Kode (Python met het pakket 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"])