モバイルウォレットのプライバシー:Android 3 財布を分解して数えた
Android ウォレット3つを展開し、マニフェストとコードを読みました。プッシュ SDK なし、クラッシュ報告なし、バックアップはクラウドに出さない。ただし既定ノードと権限は大きく違います。
スマホの中で、アドレスと残高と IP を同時に知っているソフトは1つだけです。ウォレットです。交換サイトでもエクスプローラーでもありません。鍵を持ち、同時に通信を発するのがウォレットだからです。そこで3つを開けました。2026年10月28日、各プロジェクトの GitHub リリースから arm64 の Android ビルドを取得し、パッケージ内のバイナリ AndroidManifest.xml を解析し、コンパイル済みの Dart と Java のコードから「しゃべる部品」を検索しました。プッシュ、クラッシュ報告、解析、バックアップ、そして新規インストールが既定で接続するノードです。
何を開いたか、静的解析で分からないこと。
3つのパッケージです。Cake Wallet 6.5.0(com.cakewallet.cake_wallet、versionCode 6428)は 130,627,556 バイト、2,525 エントリ、展開後 605,160,712 バイト。Monero.com 6.5.0(com.monero.app、6171)は 75,292,742 バイトで、同じコードベースから通貨を絞ったもの。Stack Wallet 2.7.1(com.cypherstack.stackwallet、2316)は 211,733,750 バイト、639 エントリ、展開後 433,735,450 バイト。手法には限界があり、一度だけ明示します。これは出荷済みビルドの静的解析であり、実行時の通信捕捉ではありません。ライブラリがパッケージ内にあることは証明できますが、見ていない先に一度も接続していないことは証明できません。ノード事業者や流動性提供者が向こう側で何を保持しているかも見えません。以下の記述はすべてバイト数、マニフェスト属性、バイナリ内に実在する文字列のいずれかで、プライバシーポリシーからの推測は含みません。 (モネロウォレットガイド)
漏洩面1:プッシュ通知。
3つのパッケージすべてで firebase/messaging、FirebaseMessagingService、gcm_defaultSenderId、OneSignal、UnifiedPush、ntfy のヒットはゼロでした。通知機構として存在するのは flutter_local_notifications のみで、これは端末上で通知をスケジュールするものです。これが重要なのは、プッシュトークンが Google や Apple のアカウントに紐づくインストール単位の安定した識別子であり、メッセージのメタデータだけで送信者に「いつ起きていて、いつオンラインか」が分かるからです。プッシュ SDK がなければ漏れるトークンはありません。ただしネットワーク側から起こしてもらう手段もなく、アプリ自身が気づく必要があります。差が出るのはここです。Stack Wallet は権限10個、service 0個、receiver 2個。Cake Wallet は権限21個、service 8個、receiver 11個で、RECEIVE_BOOT_COMPLETED、WAKE_LOCK、FOREGROUND_SERVICE_DATA_SYNC を含みます。Cake は再起動後も同期を続け、Stack は続けません。 (モネロウォレットガイド)
漏洩面2:クラッシュ報告と第三者 SDK。
3つとも Crashlytics、io/sentry、AppsFlyer、Adjust、Amplitude、Mixpanel はありません。Firebase は例外クラス名3つ(FirebaseException、FirebaseExceptionMapper、FirebaseApiNotAvailableException)だけであり、依存の残骸で、メッセージングでも解析でもありません。差は別のところにあります。Stack Wallet は com/google/android/gms の文字列が0、WalletConnect も0。Cake Wallet は Google Play services の認証・資格情報クラス(play/core 配下に70文字列)と WalletConnect の文字列88件を持ち、pulse.walletconnect.org、verify.walletconnect.org、rpc.walletconnect.org を指します。WalletConnect は dApp ブラウザを開いたときだけ動きますが、動いた瞬間に IP は自分で選んでいないリレーに届きます。クラッシュ報告は機種、OS ビルド、スタックトレースを送りますが、この3ビルドにはそれがありません。 (モネロウォレットガイド)
漏洩面3:バックアップ。
3つとも android:allowBackup="false" と android:fullBackupContent="false" を設定しています。この1つの属性が、シードフレーズが Google Drive のバックアップに同乗するかどうかを分けます。自動バックアップを切れば、Android のクラウドバックアップはアプリデータに手を出せません。代わりに使うのは自分で書き出すパスワード付きファイルで、文字列もはっきりしています(backup_service.dart、「Backup password」、「Enter backup password here」、「Incorrect backup password」)。代償も正直に書きます。鍵を Google のストレージから遠ざけるこのフラグは、書き出しをしないまま端末が壊れればウォレットごと失われることも意味します。書き出したファイルをクラウドに上げれば、開発者が外したリスクを自分で戻したことになります。オフライン媒体に書き出し、パスワードはファイルと別に保管してください。
漏洩面4:接続するノード。
新規インストールは既定のホストを解決し、そのホストはウォレットの問い合わせのたびに IP を見ます。Cake Wallet は node.cakewallet.com、mempool.cakewallet.com、ohttp.cakewallet.com を向き、DNS は cloudflare-dns.com/dns-query と dns.google.com/resolve への DoH です。Stack Wallet は nodes.nanswap.com、chain.so、chainz.cryptoid.info、mempool.space、api.coingecko.com を向きます。どちらも Tor を積んでいます。Stack は libtor_ffi_plugin.so(16,610,776 バイト)と socks5_proxy を同梱。Cake は torch_dart のバインディングと socks5_proxy を持ちますが、この APK 内に tor バイナリはないため、ファイル一覧ではなくアプリ内の Tor スイッチで判断してください。Tor は「誰が IP を見るか」をノード事業者から出口ノードへ移し、DoH は「誰が DNS 問い合わせを見るか」を ISP から Cloudflare か Google へ移します。どちらも改善で、匿名化ではありません。Cake は交換業者も同じバイナリに含み(sideShift、StealthEX、SimpleSwap、Trocador、SwapTrade、Exolix、ChangeNOW、LetsExchange)、Stack は Exolix、Trocador、ShopInBit、WizardSwap、Nanswap を含みます。交換を押した瞬間に宛先アドレスと数量を見るのはこれらの事業者です。 (モネロウォレットガイド)
漏洩面5:権限一覧。
Cake Wallet は権限21個、Stack Wallet は10個。面白いのは古い権限の絞り方です。ACCESS_FINE_LOCATION、ACCESS_COARSE_LOCATION、BLUETOOTH、BLUETOOTH_ADMIN はすべて maxSdkVersion="30" 付きで、Android 11 以前にしか存在しません。WRITE_EXTERNAL_STORAGE は 29 が上限です。Android 12 以降では BLUETOOTH_SCAN に usesPermissionFlags=0x10000(neverForLocation)が付いており、走査を位置情報の取得に使わないと宣言しています。現代の端末で実際に生きているのは、カメラ、通知、生体認証、ネットワーク状態、そして Cake ではバックグラウンドの三点セット RECEIVE_BOOT_COMPLETED、WAKE_LOCK、明示的な REQUEST_IGNORE_BATTERY_OPTIMIZATIONS です。これは不祥事ではなく設計上の選択として読むべきでしょう。バックグラウンドで同期する財布はノードへの接触が増え、ノードが見るのは1回の問い合わせではなく時刻付きのパターンになります。 (モネロウォレットガイド)
これが交換にとって何を意味するか。
注文フォームへの影響はほとんどなく、その周辺への影響は大きい。注文に必要なのは5項目(売る資産、買う資産、数量、受取アドレス、返金アドレス)で、署名は不要です。交換でウォレットは何も署名しないため、交換サイトのログ方針は全体の半分にすぎません(残り半分は別記事で書きました)。ウォレットが握る半分は、どの IP が受取チェーン上のそれらのアドレスと一緒に現れるか、そして既定ノードが 09:00 に全残高を、09:05 に取引所の入金アドレスを見られるかどうかです。目安として、2026年10月28日14:12 UTC 時点の当サイトの見積りは、100 USDT-TRC20 が 0.14643508 XMR、1,000 が 1.62493375 XMR、1 XMR が 581.25007 USDT、0.05 BTC が 6.64115532 XMR(1 BTC = 132.82311 XMR)。カタログは 519 資産・73 ネットワークです。見積りは動きます。これはスナップショットであり約束ではありません。 (XMR→USDT 出口ルート)
自分の端末で5分で確認する。
私たちのスクリプトがなくても同じ確認はできます。設定 → アプリ → ウォレット → 権限を開き、カメラ、通知、ネットワーク以外の要求には理由を問うてください。次に 設定 → システム → バックアップ で、そのウォレットが自動バックアップの一覧に出るか確認します。出ていて望まないなら、アプリのバックアップを切り、自分でファイルを書き出します。adb のある PC なら adb shell dumpsys package com.cakewallet.cake_wallet を実行し、granted で絞って実際の許可状態を見てください。マニフェストの願い事ではなく実態が分かり、フォアグラウンドサービスが動いているかも見えます。第二の意見としては Exodus Privacy の同一バージョンのレポートが内蔵ライブラリを独立に一覧化しています。いずれもサーバー側の挙動は証明できず、パッケージの中身だけを示します。
短くまとめると。
この3ビルドでは、ウォレットは漏れる側ではありません。プッシュトークンもクラッシュ報告もクラウドバックアップのフラグもありません。残るのは地味で決定的な部分です。IP を見る既定ノード、そしてバックグラウンド同期するアプリが単発の問い合わせではなくパターンを生むという事実です。まずその層を直してください。アプリ内の Tor スイッチを入れるか自前のノードに向ける、自動バックアップは切ったまま自分で暗号化ファイルを書き出す、注文ごとにアドレスを分ける、取引所の入金アドレスを返金先に使わない。以上はすべて 2026年10月28日時点の3つの APK の静的解析です。バージョンは変わるので、実際にインストールしたビルドで再確認してください。 (Torでのスワップは安全?)