How it works
データの扱いと暗号化のしくみ
入力した記録がどこで暗号化され、サーバーに何が残り、運営者に何ができて何ができないのか。CarKeep のしくみを、守れないことも含めてそのまま説明します。
しくみを公開する理由
入力したデータがどう扱われるかを、使う人は知ることができるべきだと考えています。そして CarKeep の安全は、しくみを隠すことではなく、鍵があなたの Passkey の中にしかないことで成り立っています。しくみが知られても、鍵がなければ記録は読めません。
Web 版の画面のプログラムは、もともとブラウザにそのまま届いているので、調べようと思えば誰でも中身を読めます。このページは、それを読まなくても分かるように書いたものです。
一方で、ソースコードは今のところ公開していません。このページは運営者による説明で、第三者が確かめたものではありません。自分で確かめられる範囲は「確かめる方法」に書きました。
このページに書かないのは、招待や登録の具体的な手順と、サービスの運用(管理の作業をどこでどう行うか)の詳細です。これらは記録の安全には関係せず、書くと攻撃の手がかりになるためです。
全体の流れ
記録は、あなたの端末(ブラウザまたは iPhone アプリ)の中で暗号化してから送ります。サーバーは暗号文を預かって端末どうしで受け渡すだけで、中身を読むことも、並べ替えや燃費の計算をすることもありません。それらはすべて端末が復号してから行います。
あなたの端末
平文はここだけ
入力 → 暗号化
受け取り → 復号 → 表示・燃費の計算
サーバー(Cloudflare)
鍵を持たない
暗号文を預かり、
他の端末へ受け渡す
サーバーは Cloudflare の上で動いています。通信は HTTPS で暗号化され、Cloudflare で一度ほどかれますが、その中身の記録はさらに端末で暗号化されているので、Cloudflare からも読めません(配信するプログラムを書き換えられた場合は別です。「この暗号化で守れないこと」を参照)。
iPhone アプリをアカウントなし(「このiPhoneだけで使う」)で使う場合は、記録をどこにも送りません。このページの以下の内容は、アカウントで使う場合の話です。
鍵のしくみ
記録を暗号化する鍵(データ鍵)は、アカウントごとに 1 つ、最初に記録を開いた端末が乱数で作ります。データ鍵は、Passkey から作った別の鍵で包んで(暗号化して)からサーバーに預けます。Passkey がなければ包みを開けないので、サーバーにある包まれたデータ鍵だけでは何もできません。
Passkey
PRF で秘密の値を取り出す(端末の中だけ)
Passkey ごとの鍵
HKDF-SHA256 で作る(端末の中だけ)
データ鍵
アカウントに 1 つ、ランダムな 256 bit。Passkey ごとの鍵で包んでサーバーに預ける
記録・Passkey の名前
データ鍵と AES-256-GCM で暗号化してサーバーに預ける
- Passkey の
PRFという機能で、Passkey ごとに決まった秘密の値を端末の中で取り出し、そこから鍵を作ります。ログインの署名に使う秘密鍵とは別のもので、署名用の秘密鍵は CarKeep にも取り出せません。この値と、そこから作った鍵は端末の外に出しません。サーバーは、この値を含んだログインの応答を受け取ると拒否します。 - PRF に対応していない Passkey でもログインはできますが、鍵を作れないので記録は開けません。その場合は画面でお知らせします。
- Passkey を追加するときは、今の Passkey でデータ鍵を開き、新しい Passkey の鍵で包み直して預けます。データ鍵そのものは変わらないので、どの Passkey でも同じ記録を開けます。
- 暗号文には、どのアカウントの、どの記録のものかを結び付けてあります(AES-GCM の追加認証データ)。サーバーが暗号文を別の記録や別の人のものと入れ替えても、復号の段階で失敗します。
- 中身は、決まった大きさ(256 byte)単位で空白を足してから暗号化します。暗号文の大きさから、給油か整備かといった記録の種類は分かりません。
- 暗号の処理は自作せず、Web はブラウザ標準の WebCrypto、iPhone は Apple の CryptoKit を使っています。Web と iPhone が同じ入力から同じ暗号文を作ることを、共通のテストデータで確かめています。
- Passkey をすべてなくすと、データ鍵を開ける手段がなくなり、運営者にも記録を戻せません。戻せる裏口を作っていないためです。Passkey は 2 つ以上登録しておくと安心です。
ログインから記録を開くまで
- 1.Passkey でログイン(Face ID など)。同時に PRF の値を端末の中で受け取る
- 2.署名を公開鍵で確かめ、その Passkey で包んだデータ鍵を返す
- 3.PRF の値から鍵を作り、データ鍵の包みを開く
- 4.暗号文を受け取り、端末の中で復号して表示する
- 5.記録を保存するときは、暗号化してから送る
- 6.暗号文を保存し、変更の通し番号を付ける(他の端末はこの番号で新しい変更に気づく)
一度開くと、データ鍵はその端末に保存されるので、次からは Passkey の確認なしで開けます(Web は取り出せない形でブラウザに、iPhone はその端末だけのキーチェーンに保存)。ログアウトすると消去します。
サーバーにあるもの
データベースにあるのは次の情報だけです。データベースがすべて外に漏れても、ここから記録を読むことも、あなたになりすましてログインすることもできません。CarKeep が付ける ID(アカウント、Passkey の登録、記録)は UUIDv7 という形式で、作った日時をミリ秒単位で含みます。
- アカウント
- ID、利用者か管理者か、最後に使った日(日付のみ。6 か月で削除するため)
- Passkey
- 登録の ID、公開鍵、Passkey そのものの ID(認証器が作るもの)、使用回数のカウンター、包んだデータ鍵、Passkey の名前(暗号化済み)
- ログイン状態
- ログイン用の値のハッシュ(値そのものは持たない)、Web か iPhone か、有効期限、最後に本人確認した時刻
- 記録
- 記録の ID(端末が作る)、変更の通し番号(他の端末が、前回より後の変更だけを受け取るため)、アカウント ID、暗号文
- 一時的な情報
- ログインの途中の確認用の値や招待の受け付けに使う値のハッシュ。期限が来れば毎日消去
暗号化されて、サーバーに分からないもの:車の名前、記録の種類、日付、走行距離、給油量、金額、製品名、タイヤ溝、どの記録がどの車のものか、Passkey の名前。
暗号化しても、サーバーに分かってしまうもの:記録の件数と、それぞれのおおよその大きさ(256 byte 単位)、アカウントを作った日時、Passkey を登録した日時、それぞれの記録を作った日時(ID に含まれます。給油日など入力した日付とは別です)、記録を保存・更新・削除した順番と時期、一度にまとめて送った記録のまとまり、Passkey の数、Web と iPhone のどちらでログインしているか。
サーバーのログには、リクエストの種類と場所(URL のパス部分)、結果、かかった時間、エラーの種類だけを書きます。送られてきた中身、ログイン用の値、URL のクエリは書きません。CarKeep として IP アドレスは保存しませんが、通信を中継する Cloudflare は通信のために IP アドレスを扱います。
運営者にできること・できないこと
できること
- アカウントを作る・削除する(記録もすべて消える)
- 招待を出す
- 「サーバーにあるもの」の情報を見る(ID、最後に使った日、Passkey の数、記録の件数と大きさなど)
できないこと
- 記録や車の名前、Passkey の名前を読む
- あなたの Passkey を使ってログインする
- Passkey をすべてなくしたアカウントの記録を戻す
- 記録を別の内容に書き換える(鍵がないので、壊すか消すことしかできない)
ただし「できないこと」は、次の「守れないこと」にある方法を運営者が取らない限りの話です。
この暗号化で守れないこと
暗号化は万能ではありません。次の場合は、記録を読まれる可能性があります。
Web 版の画面のプログラムが書き換えられた場合
Web 版は、開くたびに画面のプログラムをサーバーから受け取ります。運営者や、運営者のアカウントを乗っ取った人、配信を担う Cloudflare がそのプログラムを書き換えると、次に開いたときに、暗号化する前の記録や鍵を別の場所へ送らせることができます。Web で使う以上、これは CarKeep に限らず避けられない弱点で、あなたは運営者を信用することになります。
iPhone アプリが書き換えられた場合
iPhone アプリは Apple の審査と署名を通ったものだけが配られるので、Web 版より書き換えにくくなっています。それでも、運営者が悪意のあるアップデートを出すことはできます。
端末やブラウザが乗っ取られた場合
端末のウイルス、信用できないブラウザの拡張機能、端末そのものを他人に使われた場合は守れません。保存したデータ鍵は取り出せない形ですが、そのブラウザや端末を使える人は記録を開けます。共用のパソコンでは、使い終わったらログアウトしてください。
Passkey を管理するサービスが破られた場合
鍵のもとになる値は Passkey から作られます。iCloud キーチェーンやパスワード管理アプリなど、Passkey を保管しているサービスの安全に頼っています。
暗号化していない情報
「サーバーに分かってしまうもの」に書いた、件数・大きさ・時期などは暗号化できません。
よくある疑問
Passkey の秘密鍵から暗号の鍵を作っているのですか?
いいえ。ログインの署名に使う秘密鍵は認証器(iPhone やパスワード管理アプリなど)の中にあり、CarKeep を含めどのアプリも取り出せません。署名の結果から鍵を作ることもしていません。暗号の鍵には、WebAuthn の prf 拡張(認証器によっては hmac-secret)を使います。認証器は Passkey ごとに署名用とは別の秘密を持っていて、CarKeep が決めた入力(carkeep/prf/v1)からその秘密で計算した 32 byte の値だけを返します。CarKeep はこの値から HKDF-SHA256 で鍵を作り、その鍵でデータ鍵を開きます。この値はログインの応答とは別に端末の中で受け取り、サーバーへは送りません(含まれていればサーバーが拒否します)。
機種変更や、別の端末で開くときはどうなりますか?
iCloud キーチェーンやパスワード管理アプリで同期される Passkey は、新しい端末でも同じ秘密を持っているので、同じ値が返ります。新しい端末でその Passkey を使ってログインすれば、サーバーに預けてある「包んだデータ鍵」を開けます。同期されない Passkey(セキュリティキーなど)を新しく使う場合は、記録をすでに開けるブラウザで、Web 版の「セキュリティ」画面から追加します。今の Passkey で開いたデータ鍵を、新しい Passkey から作った鍵で包み直して預けるしくみです。どちらの場合も、サーバーが受け取るのは包んだデータ鍵だけで、開くための値は受け取りません。そのため運営者が鍵を復元してあげることはできず、Passkey をすべてなくすと記録は戻りません。
Web 版のプログラムは誰が配信していて、悪意のあるものに差し替えられたら?
CarKeep の運営者が、Cloudflare を通して配信しています。差し替えられた場合に記録を読まれうることは「この暗号化で守れないこと」に書いたとおりで、端末で暗号化するしくみ全般に共通する課題です。CarKeep では CSP で、CarKeep 以外から来たスクリプトを実行せず、画面からの通信(fetch など)の宛先を CarKeep 自身に限っています。これで第三者がスクリプトを差し込む攻撃は防げますが、配信元でのプログラムの差し替えは防げません。この心配を減らしたい場合は、Apple の審査と署名を経た iPhone アプリを使うか、記録をどこにも送らない「このiPhoneだけで使う」で使ってください。
削除
- 記録を削除すると、暗号文を消します。他の端末に削除を伝えるため、記録の ID、変更の通し番号、アカウント ID だけが残ります。
- 車を削除すると、その車の記録もまとめて削除します。
- アカウントを削除すると、Passkey、ログイン状態、記録をすべて消し、何も残しません。
- 6 か月間使われていない(ログインも、ログインした状態での閲覧もない)アカウントは、毎日の自動処理で同じように削除します。
- 消したデータは、データベースの障害に備えた復元用の履歴に、しばらくの間(暗号文のまま)残ることがあります。
確かめる方法
ソースコードは公開していませんが、パソコンのブラウザがあれば、送られている中身は確かめられます。
- パソコンの Chrome や Safari で CarKeep にログインし、開発者ツールの「ネットワーク」を開きます。
- 記録を保存すると、
/api/v1/recordsへの送信が表示されます。その中身のciphertextが、入力した内容とは似ても似つかない英数字の並びになっていることが分かります。 - ページの応答ヘッダーの
Content-Security-Policyで、CarKeep 以外から来たスクリプトを実行しないこと、画面からの通信の宛先を CarKeep 自身に限っていることも確かめられます(配信元でのプログラムの差し替えまでは防げません)。
しくみを変えたときは、このページも更新します。保存する情報やその使い方については、プライバシー方針もご覧ください。
2026年10月20日 公開