コンテンツへスキップ
HexaTransfer
ブログへ戻る
暗号化とセキュリティ

クライアントサイド暗号化とは?ブラウザが暗号化する仕組み

クライアントサイド暗号化とはアップロード前にブラウザでファイルを暗号化すること。最大限のプライバシーとコントロールを実現。

クライアントサイド暗号化とは、ブラウザまたはアプリがネットワークに触れる前に、デバイス上でファイルを暗号化することです。サーバーが受け取るのは AES-256-GCM の出力である暗号文のみで、ランダムなノイズと見分けがつきません。復号鍵はクライアントを離れることがありません。これはサーバーサイド暗号化の逆です。サーバーサイドでは、プロバイダーが鍵を保持しており、技術的にはファイルを読めます。W3C が2017年に標準化した Web Crypto API(window.crypto.subtle)により、プラグインなしであらゆる現代ブラウザで利用可能です。AES-NI ハードウェアでは約2〜3 GB/s で動作します。HexaTransfer・SwissTransfer・Tresorit Send・Proton Drive はこのモデルを採用しており、サービス自体が侵害されてもファイルのプライバシーが保証されます。

ブラウザが暗号エンジンになった転換点

5年前は、本格的な暗号化にはデスクトップアプリのインストールやコマンドラインでの PGP 操作が必要でした。W3C が2017年に標準化した Web Crypto API がこれを変えました。Chrome・Firefox・Safari・Edge のいずれでも動作する JavaScript に、AES-GCM・RSA-OAEP・ECDH・HMAC・PBKDF2・SHA-256 が直接公開されています。

パフォーマンスはもはや障壁ではありません。Intel AES-NI 命令は AES-256-GCM をコアあたり3〜5 GB/s で処理します。Apple M シリーズや Qualcomm Snapdragon チップの ARM 暗号拡張も同等のスループットを実現します。中程度のラップトップで1 GB のファイルの暗号化は約300〜500 ms で完了します。

残る課題はブラウザのメモリを超えるファイルの処理です。Streams API と ReadableStream を使って4 MB のチャンクに分けて処理し、各チャンクをカウンターモード IV で個別に暗号化します。これにより10 GB 以上のファイルに対応できます。

クライアントサイド暗号化の基本的な処理フロー

典型的なブラウザベースサービスが実行するシーケンスは以下のとおりです。

// 1. 256ビット AES 鍵をランダムに生成する
const key = await crypto.subtle.generateKey(
  { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]
);

// 2. ファイルをチャンクで読み取る
const file = fileInput.files[0];
const chunkSize = 4 * 1024 * 1024;

// 3. 一意の12バイト IV で各チャンクを暗号化する
for (let offset = 0; offset < file.size; offset += chunkSize) {
  const chunk = file.slice(offset, offset + chunkSize);
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const ciphertext = await crypto.subtle.encrypt(
    { name: "AES-GCM", iv }, key, await chunk.arrayBuffer()
  );
  // 4. [iv || ciphertext] をサーバーにアップロードする
}

// 5. 鍵をエクスポートして共有 URL フラグメントに埋め込む
const keyBytes = await crypto.subtle.exportKey("raw", key);
const shareUrl = `https://example.com/d/${fileId}#k=${base64url(keyBytes)}`;

サーバーが見るのはランダムなバイト列とファイル ID だけです。鍵はユーザーのブラウザメモリと URL フラグメントにのみ存在します。

サーバーサイド暗号化より優れている理由

サーバーサイド暗号化では、プロバイダーはサムネイル生成・ウイルススキャン・検索処理・法的要請への対応などのために復号します。2023年の Apple の開示では、Advanced Data Protection が導入されるまでの iCloud バックアップは Apple がアクセスでき、有効な要請があれば米国法執行機関に提供されていたことが明らかになりました。

クライアントサイド暗号化はこれを逆転させます。鍵がプロバイダーに届かないため、次のことが保証されます。

  • 悪意ある社員には何も見えない:データベースにアクセスできるエンジニアが得るのは暗号文のみ。
  • 令状に対しても暗号文しか提供できない:プロバイダーは令状に応じて暗号化されたデータを提供しますが、鍵がなければ無意味。
  • 侵害があっても暗号文だけが漏洩する:2021年の LastPass 事件でもこの設計が示されました。弱いマスターパスワードのものは解読されましたが、大規模な平文漏洩は防がれました。
  • プロバイダーの障害でもデータは守られる:会社が倒産しても、URL(ローカルコピーの鍵)があれば復号できます。

サーバーがまだ見えるもの

クライアントサイド暗号化はファイル内容を保護しますが、すべてを隠せるわけではありません。サーバーが通常確認できるものは以下のとおりです。

  • ファイルサイズ:暗号文の長さは平文の長さに近似します(AES-GCM は暗号化ごとに16バイトのオーバーヘッドと12バイトの IV を追加します)。
  • アップロードとダウンロードの IP アドレスとタイムスタンプ。
  • TLS ハンドシェイクのセッションメタデータ(クライアントの TLS フィンガープリントを含む)。
  • 暗号化されていないファイル名:ファイル名が暗号化ペイロードに含まれていない場合に漏れることがあります。

優れたクライアントサイドサービスは、暗号文ヘッダーの一部としてファイル名も暗号化し、1 MB・10 MB・100 MB などのバケットサイズにパディングしてサイズを隠します。Tresorit と Proton Drive はメタデータ露出の内容を明示的に文書化しています。

パスワード保護付きクライアントサイド暗号化

多くのサービスでは URL フラグメントに加えてパスワードを設定できます。その流れは以下のとおりです。

  1. ブラウザがランダムな128ビットのソルトを生成し、PBKDF2-HMAC-SHA-256(60万回のイテレーション、OWASP 2023推奨)または Argon2id(memory=64 MB, iterations=3)で鍵を導出する。
  2. 導出した鍵でファイルを暗号化する。
  3. ソルトは URL フラグメントに入れ、パスワードは別の経路で伝える。
  4. 受信者がパスワードを入力すると、ローカルで鍵を再導出する。

これにより、URL だけで十分だった単一チャンネル共有が二要素認証に変わります。攻撃者はリンクとパスワードの両方が必要になります。60万回のイテレーションで PBKDF2 を使うと、現代の GPU でのオフラインブルートフォースは1回の推測に約10秒かかります。そのため40ビット以上のエントロピーが必要で、多様な文字種から10文字以上が目安です。

信頼の境界が変わる:サービスからクライアントコードへ

クライアントサイド暗号化は信頼の境界を移動させます。以前はサービスが平文を適切に扱うことを信頼していました。今度は、サービスがページ読み込みごとにブラウザに配信する JavaScript を信頼します。悪意ある更新が暗号化の前または最中に鍵を流出させる可能性があります。

これを軽減する3つの手段があります。

  • Subresource Integrity(SRI):スクリプトタグに設定し、JS のハッシュが既知の値と一致することを保証します。
  • コード監査:Cure53・NCC Group・Trail of Bits などによる監査で暗号化ロジックの正確性を確認します。
  • 再現可能なビルド:第三者が配布コードが公開ソースと一致することを確認できます。
  • Content Security Policy(CSP):暗号化を改ざんする可能性のあるサードパーティスクリプトをブロックします。

最も厳格なアプローチは Proton Mail の pmcrypto や一部の Electron ベースクライアントが採用する署名付きバイナリの配布です。ブラウザベースサービスは、インストール不要の利便性のためにこの厳密さをある程度犠牲にしています。

クライアントサイド暗号化が威力を発揮するシーン

最初の読み込みがわずかに遅くても、クライアントサイド暗号化が価値を持つシナリオがあります。

  • 法的・医療文書:HIPAA 45 CFR § 164.312 と弁護士・依頼人間の特権は、プロバイダーが見えないアーキテクチャから大きく恩恵を受けます。
  • ジャーナリズムと情報源の保護:メタデータ漏洩すら危険な状況での非編集済み文書の送信。
  • 企業の知的財産:ファイル転送プロバイダーでの内部脅威が現実的な懸念となる取締役会資料・財務モデル・M&A 関連資料。
  • 個人記録:税務書類・パスポート・医療検査結果など、プロバイダー侵害のニュースで見たくないファイル。

会議の写真やレシピのような機密性の低いファイルには、従来のサーバーサイド暗号化で十分です。

本当にクライアントサイド暗号化しているか見分ける方法

サービスが実際にクライアントサイド暗号化を実装しているかを示す4つのサインです。

  1. URL フラグメントに鍵がある:共有 URL の # 以降にランダムなバイト列を base64 エンコードしたような文字列が含まれている。
  2. アップロードが暗号文:アップロード中に DevTools → ネットワークを開くと、リクエストボディがランダムなバイトに見え、ファイル名が表示されない。
  3. 大きなファイルも高速:本物のクライアントサイド処理はチャンクをストリーミングします。サーバーサイドの暗号化ゲートウェイへの再アップロードは不要です。
  4. プライバシーポリシーに「ファイルを復号できない」と明記されている:技術的なホワイトペーパーとともに、マーケティング文句だけでなく。

これらを満たすサービス:SwissTransfer の E2EE プラン・Tresorit Send・Proton Drive 共有リンク・Mega.nz・HexaTransfer。満たさないサービス:WeTransfer(標準)・Google Drive・Dropbox 共有リンクがあります。

hexatransfer.comでお試しください — 無料、登録不要、最大10GB。

エンドツーエンド暗号化で大容量ファイルを安全に送信

エンドツーエンド暗号化で最大10GBのファイルを無料で転送。アカウント不要。ファイルはアップロード前にブラウザで暗号化されるため、他の誰にも読まれません。

ファイルを送信