1. ペアリング:信頼はMacの画面から始まる
- 各デバイスは独自のP-256鍵ペアを持ちます。iPhoneの秘密鍵はSecure Enclave内で生成され、書き出すことはできません。Secure Enclaveのないデバイスでは、そのデバイス限定のキーチェーンに保存されます。Macの秘密鍵は、あなたのユーザーアカウントだけが読み取れるファイルに保存されます。
- MacのIDは公開鍵から導出されます(公開鍵のSHA-256の先頭16バイト)。ランデブーサービスはMacに署名で所有を証明させるため、誰もそのIDを横取りしたり、なりすましたりできません。
- ペアリング用のQRコードは、Macの画面にしか表示されません。QRコードには、MacのID、その公開鍵のフィンガープリント、そして5分間有効で1回だけ使える32バイトのペアリングキーが含まれています。
- スキャン後、iPhoneはペアリングキーを使って、自身の鍵のフィンガープリントに対するHMAC-SHA256を計算します。これにより、コードを実際に見たことを証明すると同時に、その証明を自身の公開鍵に結び付けるため、途中で別の鍵にすり替えることはできません。Macはこの証明を検証し、iPhoneの公開鍵を記録します。
- 以降、双方は相手の公開鍵しか受け付けません。フィッシングやパスワードリスト攻撃の標的になるパスワードもアカウントもありません。iPhoneを追加するには、誰かがMacの前でコードをスキャンする必要があります。
2. 接続のたびに行われること
- まずFace ID。接続のたびに、iPhoneはFace IDまたはデバイスのパスコードを求めます。バックグラウンドに5分以上置いたあとで戻ったときも、再度求めます。
- 署名付きリクエスト。iPhoneはSecure Enclaveの鍵でリクエストに署名します。内容は、タイムスタンプ、ランダムなノンス、使い捨ての接続用認証情報、そして自身のネットワークアドレスです。ランデブーサービスはこれをMacに渡します。アドレスも署名の対象なので、サービスがMacを別の場所に誘導することはできません。
- 判断するのはMac。Macが受け入れるのは、ペアリング済みの鍵、2分以内のタイムスタンプ、一度も使われていないノンスを持つリクエストだけなので、古いリクエストを再送(リプレイ)することはできません。そのうえで初めてUDPポートを開き、30秒以内にセッションが始まらなければ再び閉じます。
- 経路を探す。双方は、ローカルネットワーク、STUNによるホールパンチングでルーターを越える直接経路、Cloudflare TURNの中継を同時に試します。0.6秒以内に直接経路がつながればそれを使い、そうでなければ最初につながった経路を使います。その後10秒以内に直接経路が見つかれば、DuoDeskはそちらに移ります。中継用の認証情報は、Macが接続を受け入れたあとにのみ発行されます。
- 暗号化されたセッション。その経路上で、両者はQUIC接続(TLS 1.3)を確立します。それぞれが証明書を提示し、相手の公開鍵がペアリング時に記録したものと完全に一致するかを確認します。一致しなければ、接続は切断されます。
- 自動復旧。各セッションは予備の中継経路を常に用意しており、メインの経路から約1秒応答がないとそちらに切り替えます。ネットワークが変わったときはアプリが自動で再接続し、その間あなたの入力は送信されません。
3. サーバーが侵害された場合
DuoDeskは、ランデブーサービスと中継サーバーがすでに侵害されていることを前提に設計されています。暗号化と本人確認はiPhoneとMacの間だけで行われ、サーバーは、セッションを復号したりデバイスになりすましたりできる鍵を何も持っていません。
できないこと
- 画面、入力、クリップボードを見ること:セッションは、2台のデバイスにしか存在しない鍵でエンドツーエンドで暗号化されています。
- MacやiPhoneになりすますこと:双方が、ペアリング時に記録した公開鍵を確認します。
- 新しいiPhoneをMacとペアリングすること:Macの画面にしか表示されない使い捨てのキーが必要です。
- 古い接続リクエストを再送すること:すべてのリクエストに、タイムスタンプと使い捨てのノンスが含まれています。
最悪の場合にできること
- 接続を失敗させること。
- どのIPアドレスが、いつ、どのMacに接続したかを知ること。
- スタンバイパネルに偽のタスク状態を表示すること:ライブアクティビティのプッシュは、プッシュキーを持つこのサービスを経由してAppleに送られます。
通常の運用時にサービスが見るもの・保存するものは、プライバシーポリシーに記載しています。
4. ランデブーサービスに許されていること
- Cloudflare Workers上で動作し、MacごとにDurable Objectを1つ使います。Macはサービスへ外向きに接続し、署名を使って登録するだけです。サービスがペアリングキーやデバイスの秘密鍵を必要とすることはなく、受け取ることもありません。
- 接続リクエストはそのままMacに渡されます。サービスが読み取るフィールドは、プッシュトークンだけです。
- 中継(TURN)の認証情報は、Macが接続を受け入れたあとにのみ発行され、12時間で失効します。
- プッシュの中継が通すのはライブアクティビティのプッシュだけで、送信先はそのMacに接続したことのあるiPhoneに限られ(サービスが保持するのは各トークンのハッシュだけです)、チャンネルもそのMacが作成したものに限られます。プッシュキーはMacアプリに同梱せず、サービス内にとどめています。
- 不正利用の制限:1つのIPアドレスから1台のMacへの接続リクエストは1分あたり最大30件、Macごとの保留中の接続は最大8件、メッセージは最大8 KBです。
5. Mac上の保護
- インターネットに開いたポートはありません。通常、Macが持つのはランデブーサービスへの外向きの接続1本だけです。セッションのQUICリスナーはループバックアドレスにバインドされ、外部向けのUDPポートは検証済みのリクエストに対してのみ開きます。
- プライバシースクリーン。接続中、DuoDeskは物理ディスプレイのガンマテーブルを黒に設定します。ガンマは画面の合成後に適用されるため、iPhoneに届く画面には影響しません。また、DuoDesk Hostが終了またはクラッシュした場合はmacOSが自動でガンマを元に戻すため、画面が暗いままになることはありません。
- 接続解除時のロックとアイドルタイムアウト。接続を解除したとき、DuoDeskは、システムの「画面をロック」コマンドと同じ仕組みでMacをすぐにロックできます。15分間入力がないと、セッションは自動的に終了します。
- 接続が見える。誰かが接続している間はメニューバーのアイコンが変わり、すべての接続と切断、およびその理由が、Macのローカルの接続ログに記録されます。
- 署名と公証。DuoDesk HostはDeveloper IDで署名され、Appleの公証を受け、Hardened Runtimeで動作します。入力を実行するにはアクセシビリティ権限が必要ですが、サンドボックス化されたアプリはこの権限を持てないため、Mac App Storeでは配信していません。代わりに、このWebサイトからダウンロードしていただけます。
6. 画面、入力、実測値
- 画面はScreenCaptureKitで最大60 fpsでキャプチャし、変化がないときはフレームを送りません。VideoToolboxでH.264またはHEVCにハードウェアエンコードし、低遅延のレート制御を使い、Bフレームは使わず、ビットレートはネットワークに合わせて調整します。
- Macに、iPhoneの解像度に合わせた仮想ディスプレイを追加でき、拡大縮小なしの1:1で表示します。
- ポインタはiPhone上ですぐに描画され、その後でMac側と突き合わせるため、ネットワークを待つことはありません。iPhoneは120 Hzで描画します。
実測値
| 環境 | 経路 | 往復時間(中央値) | スループット |
|---|---|---|---|
| MacはコワーキングスペースのWi-Fi、iPhoneは5G | ホールパンチングによる直接接続、約0.1秒で確立 | 30 ms | 58 Mbps |
| 両方とも同じコワーキングスペースのWi-Fi(デバイス同士は通信不可) | Cloudflareの中継、約1秒後に切り替え | 18 ms | 69 Mbps |
2026年10月にシンガポールで、DuoDeskのトランスポート層(ホールパンチングまたは中継を経由するQUIC)を測定した結果です。画面ストリームのデフォルトは12 Mbpsです。結果はお使いのネットワークによって異なります。
7. 既知の制限
- Macにはユーザーがログインしている必要があります。画面のロックは問題ありません。FileVaultが有効なMacは、再起動後、ネットワークが使えるようになる前のロック解除画面で止まり、そこにはどのリモートツールも届きません。
- DuoDeskはUDPで接続するため、UDPを完全にブロックしているネットワークでは使えません。
- macOSは約30日ごとに、画面収録の確認を改めて求めます。それによって画面がブロックされた場合は、誰かがMacの前で「許可」をクリックする必要があります。
- ランデブーサービスは、接続のメタデータを見ることができます(セクション3を参照)。