CryptoKitでデータを暗号化してみた話

CryptoKitでデータを暗号化してみた話 トラブルシューティング

Xcode Instrumentsでのパフォーマンス改善に取り組んだあと、端末に保存する記録データ自体をもう少し保護したくなり、CryptoKitでの暗号化に挑戦しました。

1. Keychainがあれば暗号化は不要だと思い込んでいた

以前Keychainについて調べたときの知識から、機密データはKeychainに入れておけば安心だと思い込み、CryptoKitの出番を見誤っていました。

Keychain: 短いデータ(トークン、パスワードなど)の安全な保管に向く
CryptoKit: 大きめのデータ(記録の本文など)を自分で暗号化してから保存するのに向く

Keychainは容量や用途の面で、まとまった量のデータを保存するのにはあまり向いていません。記録データ本体のような大きめの情報は、CryptoKitで暗号化した上で通常のファイルやデータベースに保存し、暗号化に使う「鍵」だけをKeychainで安全に保管する、という役割分担が実態に合っていると分かりました。

2. 暗号化のたびに鍵を作り直してしまっていた

実装したばかりの頃、暗号化する処理を書くたびに新しい鍵を生成していたため、一度暗号化したデータが二度と復号できなくなる不具合を起こしてしまいました。

let key = SymmetricKey(size: .bits256)

このコードを呼び出すたびに、毎回まったく新しい鍵が生成されてしまいます。同じデータを後で復号する必要がある場合は、鍵を一度だけ生成してKeychainに保存し、以降はその保存済みの鍵を読み込んで使い回す必要がありました。「暗号化=毎回新しい鍵」という誤解に気づくまで、意図せずデータを失う実験を何度か繰り返してしまいました。

3. 暗号化したデータのサイズが想定より大きくなった

暗号化前後でデータサイズを比較したところ、想定していたよりもファイルサイズが大きくなっていることに気づきました。

CryptoKitの暗号化処理には、改ざん検知のための情報(認証タグ)などが付加される仕組みになっており、単純な暗号化以上のデータが追加されます。安全性を高めるための必要なオーバーヘッドだと理解し、サイズの見積もりをその分あらかじめ大きめに取るよう設計を調整しました。

4. 圧縮と暗号化の順序を間違えていた

保存前にデータを圧縮する処理も入れていたのですが、暗号化した後に圧縮をかけたところ、ほとんどサイズが縮まらないことに気づきました。

正しい順序: 圧縮 → 暗号化
誤っていた順序: 暗号化 → 圧縮

暗号化されたデータはランダムに近いバイト列になるため、圧縮アルゴリズムがパターンを見つけられずほとんど効果を発揮しません。先に圧縮してから暗号化する順序に直したところ、想定通りサイズを縮められるようになりました。

まとめ

  • Keychainは小さな機密情報向け、CryptoKitはまとまったデータを自分で暗号化する用途に向く。両者を組み合わせ、暗号化の鍵をKeychainに保管するのが実用的
  • 暗号化のたびに新しい鍵を生成すると、以前のデータが復号できなくなる。鍵は一度生成してKeychainに保存し、使い回す
  • 暗号化後のデータは認証タグなどが付加され、元データよりサイズが大きくなる
  • 圧縮と暗号化を両方行う場合は「圧縮してから暗号化する」順序を守らないと、圧縮効果がほとんど得られない

「暗号化すれば安全」という一言では片付けられない、鍵の管理と処理順序への配慮が必要な実装でした。


本記事は生成AI(Claude)を活用して執筆・編集しています。内容は実体験に基づき、執筆者本人が確認・監修しています。

コメント

タイトルとURLをコピーしました