iOSのパスコード変更のコストについて


こちらの記事が大変面白かった。
iPhoneの「バックドア」問題について

記事の中で紹介されていたAppleの iOSのセキュリティ iOS Security Guide が非常に充実していて少し驚いた。

パスコードは端末の表示状態のロックを解除するだけかと思っていたら、そうではなく、iOSのコンテンツが実質的にパスコードで暗号化されているのだった。
なおかつ、パスコードを変更しても、ファイルを再暗号化しなくてもいいようになっている。

鍵マークを * で表すと
[ハードウェア鍵 + パスコード鍵] -> [クラス鍵 *] -> [ファイル鍵 *] -> [ファイルの内容 *]
となっていて、ファイルの内容はファイル鍵で、ファイル鍵はクラス鍵で、そしてクラス鍵はハードウェア鍵とパスコード鍵で、それぞれ階層的に保護されている。
文中の「ファイルのクラスを変更する場合はそのファイルのファイル鍵をラップし直すだけでよく、パスコードを変更した場合はクラス鍵のラップだけが変更されます」の部分について、簡潔すぎるので補足説明してみる。

ファイル鍵は256bitの秘密鍵である。乱数から生成され、ファイル毎に異なる(暗号化ファイル同士を比較して平文を推測したりできないようにするため)。
ファイルの内容はファイル鍵によりAESで暗号化される。これは普通のブロック暗号化である。ファイル鍵はSecure Enclave内だけで処理され、Secure Enclaveの外に出るときにはクラス鍵で暗号化して保護するようになっている。
クラス鍵はファイル鍵を保護するための256bitの秘密鍵であり、ファイル鍵はクラス鍵で暗号化されて、ファイルのメタデータ領域に保存される。クラス鍵もまた、Secure Enclave内だけで処理され、Secure Enclaveの外に出るときにはハードウェア鍵とパスコード鍵で暗号化するようになっている。(ここは単純なAESではないようだ)

このように階層化すると、実質的にはファイルをパスコードで保護しつつ、パスコードなどを変更したときのコストを減らすことができる。たとえばパスコードを変更したときは、暗号化されたクラス鍵を再暗号化(今の鍵で復号してから、新しい鍵で暗号化すること)すればよい。クラス鍵=秘密鍵そのものは変更しない。一階層下のファイル鍵はクラス鍵で暗号化されているので、クラス鍵が同じなら暗号化されたファイル鍵はそのまま使える。
同様に、ファイルのクラスを変更するとき(ファイルのオーナーを変更するときとか?)は、暗号化されたファイル鍵だけを再暗号化すれば、新しいクラスで保護することができる。この場合もファイル鍵は同じなので、ファイルの内容自体を再暗号化しなくて済む。(ファイル全体の再暗号化はコストが大きいので避けたい)

ハードウェア鍵とパスコード鍵によってクラス鍵を暗号化するときには、PBKDF2のような反復的な処理が用いられていて、総当り攻撃がやりづらくなるよう、ある程度時間がかかるように調整されている。

余談だが似たようなトピックとして、WinZIPのAES暗号化も、パスワードをPBKDF2で攪拌したものを秘密鍵としてAESで暗号化するのだが、パスワードから生成された鍵そのものでファイルの内容を暗号化するため、パスワードを変更するにはファイルの内容全てを再暗号化する必要がある。(ZIPには色々フォーマットがあるので、もしかすると賢いものも存在するかもしれない)