[iOS] Keychainのバックアップについて調べた


概要

iOSアプリでは暗号化に使ったキーをKeychainに保存するケースはあると思います。
あるユーザが機種変更で「バックアップから復元したらアプリ起動できなくなった」という出来事に遭遇しました。
それは、Keychainに保存してあったキーがバックアップされてなかったことが原因でした。

Keychainのバックアップがどうなっているのか調べた結果をまとめました。

iTunesバックアップの場合

iTunesバックアップから復元する時、暗号化してバックアップした場合とそうでない場合にKeychainが対象となるかが分かれるようです。デフォルトは暗号化オフの状態になっています。

バックアップ方法 結果
暗号化してバックアップ Keychainは対象となる
暗号化せずにバックアップ Keychainは対象とならない

但し、Keychain の kSecAttrAccessible が以下のどれかである場合のみのようです
- kSecAttrAccessibleWhenUnlocked
- kSecAttrAccessibleAfterFirstUnlock
- kSecAttrAccessibleAlways

kSecAttrAccessibleXXXThisDeviceOnlyを付けた場合は他の端末ではアクセスできなくなります。

iCloudバックアップの場合

KeychainをiCloudバックアップの対象とするには、iOS7以上でアプリ側で以下の設定を行う必要があるようです。

Synchronizing Keychain items
Items without kSecAttrSynchronizable = kCFBooleanTRUE are not synchronized (default)
Limited to passwords (kSecClassGenericPassword and kSecClassInternetPassword)

Security and Privacy in iOS 7 https://developer.apple.com/videos/play/enterprise/17/

また、ユーザがiCloudの設定でiCloudキーチェーンを有効にしていないとKeychainはバックアップされません。

Keychain OSSライブラリ

Keychainを操作したい場合にOSSライブラリを使うことが多いと思いますが、それぞれ有名なOSSがどうなっているか調べてみました。

OSS名 kSecAttrSynchronizable kSecClass kSecAttrAccessible
SAMKeychain ◯ デフォルトでON ◯ kSecClassGenericPasswordのみ ◯ 指定可
KeychainAccess ◯ 指定可 ◯ kSecClassGenericPassword, kSecClassInternetPasswordのどちらか ◯ 指定可
LUKeychainAccess ✕ OFFのみ ◯ kSecClassGenericPasswordのみ ◯ 指定可

LUKeychainAccessは kSecAttrSynchronizable の指定が出来ませんでした。

まとめ

  • iTunesバックアップ と iCloudバックアップ では Keychain が対象になる条件が異なる
  • Keychainをバックアップする目的で使うなら、OSSは SAMKeychain または KeychainAccess が良さそう
  • そもそもユーザ操作による影響が大きいので、Keychainにいれたデータは失われるものとしてアプリを設計するのが吉

参考