Kode

Kodeがコードを保存するしくみ

Kodeが2段階認証の鍵をどこに保存し、どう同期し、どうやって取り出せるか。

あなたのキーチェーンだけに

各アカウントは、コードの元になる秘密鍵も含めて、iPhoneのキーチェーンに1つの項目として保存され、最初のロック解除後に使えるようになります。鍵がアプリのデータベース、設定、ログファイル、分析、クラッシュレポートに保存されることはありません。

iCloudキーチェーン

同期がオン(初期設定)の場合、項目は同期可能として保存され、iCloudキーチェーンがほかのAppleデバイスや新しいiPhoneに届けます。iCloudキーチェーンはエンドツーエンドで暗号化されています。同期をオフにすると、鍵はこのiPhoneだけ(「このデバイスのみ」)に移され、ほかのiPhoneには引き継がれません。

サーバーなし

Kodeはネットワーク通信を行いません。コードはTOTP規格(RFC 6238)に従い、HMAC-SHA1/256/512で計算されます。Google Authenticatorと同じコードです。

ロック

アプリを開いたとき、そしてバックグラウンドに1分以上あったときにFace IDまたはパスコードを求めます。アプリがアクティブでない間はロック画面がすべてを覆うので、Appスイッチャーにコードが映ることはありません。コピーしたコードは60秒後にiPhoneのクリップボードから消えます。ユニバーサルクリップボードでMacにペーストでき、Mac上ではほかのものをコピーするまで残ります。

バックアップファイルの形式

暗号化バックアップはJSONファイルです。鍵はパスワードからPBKDF2-HMAC-SHA256(600,000回、16バイトのソルト)で導出され、内容はAES-256-GCMで暗号化されます。ciphertextは暗号文の後に16バイトのGCMタグが続いたものです。バイナリのフィールドはすべてBase64です。

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

復号すると、内容はアカウントのリストです。各アカウントには、ほとんどのアプリで読み込めるotpauth://形式のアドレスも含まれています。

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

Kodeを使わずにファイルを復号する方法(Python、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"])