RECryptorの仕組み

記録を残す。
映像は守る。

撮影した映像は残したい。でも、後から自由に見られるのは困る。
RECryptorは、映像に鍵をかけて記録し、必要なときに運営が開く仕組みです。

まず、3つの技術を知ろう

それぞれ、違う不正への対策です。「何のために使うか」から見ると、仕組みが分かりやすくなります。

勝手な再生への対策

暗号化

悪い人が勝手に映像を見ることを防ぐ。

映像を、そのままでは再生できないデータに変えます。ファイルを拾った人でも、正しい鍵がなければ元の映像へ戻せません。

映像を読めないように守る
書き換えを見つける対策

ハッシュ

悪い人がファイルを書き換えて、ごまかすことを防ぐ。

内容から短い「指紋」を計算し、元の指紋と比べます。書き換えそのものを止めるのではなく、書き換えがあったことを見つける仕組みです。

元の内容と同じかを比べる
偽の証明への対策

電子署名

悪い人が運営に成りすますことを防ぐ。

受信証明について「本当に運営の署名か」を確かめます。運営を名乗る偽の証明や、署名後に内容を変えた証明を見分けます。

正しい運営の署名かを確かめる

ハッシュだけでは十分ではありません。 書き換えたデータの指紋を、誰でも計算し直せるからです。RECryptorは指紋に運営の署名を付けて、「運営が受け付けた指紋」を後から確かめられるようにします。

暗号化で映像を守り、ハッシュと電子署名で、保存した記録が書き換えられていないかを確かめます。

あなたはファイルを、運営は鍵を持つ

1 撮影して保存

映像に鍵をかける

スマホの中で映像と音声を、そのままでは再生できないデータに変えます。これが「暗号化」です。

2 別々に保管

ファイルはあなたが持つ

撮影後に暗号文ファイルを保存します。運営は元に戻すための秘密鍵を保管します。

3 警察・裁判所の要請

運営が要請を確認して開く

警察・裁判所などの要請を運営が確認し、あなたから受け取ったファイルを元の映像へ戻します。これが「復号」です。

通常の撮影では、映像も暗号文ファイルもサーバへ送りません。撮影者自身も、保存したファイルを通常の操作では再生できません。

公開鍵と秘密鍵って、何?

まず「鍵」は、ここでは金属の鍵ではなく、コンピューターの計算に使う情報のことです。

普通の鍵は、同じ鍵で閉めたり、開けたりします。ところが、公開鍵を使う暗号では、閉めるときの鍵と、開けるときの鍵を分けられます。 公開鍵は「閉める鍵」、秘密鍵は「開ける鍵」の役割だと考えてください。

公開鍵=閉める鍵

映像に鍵をかける計算で使います。撮影するスマホへ渡して構いません。これだけでは元の映像へ戻せません。

知られても、これだけでは開けない

秘密鍵=開ける鍵

元の映像へ戻す計算に必要な、再生用の秘密鍵です。運営が保管し、利用者へは渡しません。

運営が秘密にしておく

撮影を終えると、閉めた本人でも、保存した映像を通常の操作では再び開けない。これが、記録を残しながら映像を守るRECryptorの仕組みです。

RECryptorでは、運営の「開ける鍵」を利用者へ渡しません。撮影中だけ使う鍵もファイルには残しません。実際の計算では、公開鍵と秘密鍵を使って、映像にかける作業鍵を作ります。

撮影するスマホにも、別の鍵がある

ここが少しややこしいところです。「運営が保管する再生用の秘密鍵」と「スマホが撮影の準備で作る一時秘密鍵」は、別物です。 運営の秘密鍵をスマホへ渡しているわけではありません。

撮影の準備

スマホが一時秘密鍵を作る

その撮影だけの、使い続けない鍵です。対応する一時公開鍵も作ります。運営の再生用秘密鍵とは別のものです。

撮影中

映像にかける作業鍵を計算する

一時秘密鍵と、運営から受け取った公開鍵を使って計算します。この作業鍵を使い、映像を少しずつ暗号化します。

撮影後

ファイルに秘密の鍵は残さない

一時秘密鍵と作業鍵はアプリが使う間だけ扱い、ファイルには保存しません。ファイルに入るのは、一時公開鍵などの公開情報です。

警察や裁判所の要請で復号するとき

運営が同じ作業鍵を作り直す

運営の再生用秘密鍵と、ファイル内の一時公開鍵を使います。その作業鍵で元の映像へ戻せます。

「運営の秘密鍵を利用者が持たない」と「撮影中のスマホにも鍵がある」は、両立します。持っている鍵の種類と役割が違うからです。

運営の再生用秘密鍵はメールアドレスごとに1つです。同じメールを別の端末で確認しても同じ鍵を使います。一方、スマホの一時鍵と映像の作業鍵は、撮影ごとに変わります。

映像を送らずに、改ざんをどう確かめる?

鍵をかけることは、映像を見られないようにするためです。もう一つ、後から内容を書き換えられていないかを確かめる仕組みもあります。

内容の「指紋」を計算する

暗号文から短い値を計算します。これを「ハッシュ」といいます。内容が変わると値も変わるので、照合に使えます。

運営がその指紋に署名する

運営は、指紋・撮影ID・順番・受け付けた時刻に電子署名を付けます。これが「受信証明」です。

運営が受け取るのは指紋などの小さな情報です。映像そのものではありません。指紋から映像を取り出すこともできません。

撮影から保管まで、何が行き来する?

左はあなたのスマホ、右は運営サーバです。①から⑧まで、同じ2本の線に沿って読んでください。

あなたのスマホ運営サーバ
  1. ① 撮影開始「撮影を開始する」を押す

  2. 撮影中は②〜⑥を約1秒ごとに繰り返す

    ② 暗号化暗号文の保存・指紋の計算

  3. ③ スマホ → サーバ指紋・撮影ID・順番を送る映像・暗号文ファイルは送らない

  4. ④ 指紋に署名指紋・順番・時刻を記録

  5. ⑤ サーバ → スマホ署名付き受信証明を返す

  6. ⑥ ブラウザに保存する暗号文に受信証明を追加して残す

  7. ⑦ 撮影終了「撮影を終了して保存する」を押す。最後の暗号文と終了証明も保存

  8. ⑧ ブラウザからダウンロードして安全な場所に保存する「暗号文を保存」を押し、ファイルをあなた自身で保管する

約1秒は目安です。端末の処理や通信の状況によって間隔は変わります。

電子署名も、2つの鍵で働く

署名には、映像の再生とは別の鍵の組を使います。運営だけが持つ「署名用秘密鍵」で署名を作り、誰でも持てる「署名検証用公開鍵」でその署名を確かめます。

署名用秘密鍵運営が署名を作る
署名検証用公開鍵誰でも署名を確かめる

受信証明は暗号文ファイルにも入ります。後からファイルの指紋を計算し直して、署名された指紋と比べます。順番もつなげているので、途中の削除や入れ替えを検出できます。

最後には終了証明を付けます。それがない中断ファイルは、正常に終わった完全な記録とは区別します。

改ざんを物理的に止めるというより、改ざんされたかを検出する仕組みです。公開鍵を持っていても、運営の署名を作ったり映像を再生したりはできません。

時計は、1つだけを信じない

時計が1つだけだと、ずれていても気付きにくいですよね。RECryptorは、外部時計を使う設定では、既定でNICT・Cloudflare・NISTの3系統に時刻を問い合わせます。

近い時刻を示す多数派があれば、その中央の時刻を使います。例えば、次のような場合です。

採用する12:00:00

時計A

採用する12:00:01

時計B

採用しない12:05:00

時計C

この例では、近い2つが3つのうちの多数派です。2つの間の時刻を参照し、1つの時計がずれていたことも記録します。

既定では、同じグループの時計の差が2秒以内なら近いと扱います。多数派が決まらない、問い合わせに失敗する、古い時刻情報しかない場合は、運営サーバの時刻へ切り替え、その旨を記録します。

記録するのは、運営が情報を受け付けた時刻です。実際にカメラで撮影した瞬間を、第三者が保証する仕組みではありません。

誰が、何をする?

撮影する人、鍵を保管する運営、要請する機関には、それぞれ別の役割があります。

RECryptorを使う人と、その役割

利用者

  • メールを確認して撮影する
  • 暗号文ファイルを保管する
  • 鍵の保管状況を確認する

復号するときは
運営へファイルを渡す

運営

  • 再生用の秘密鍵を保管する
  • 指紋を受け付けて署名する
  • 要請を確認して復号する

鍵と受け取ったファイルで
映像を元に戻す

警察・裁判所など

  • 運営へ所定の要請をする
  • 対象の記録を運営に示す

再生用の秘密鍵を
持っているわけではない

誰が、どの情報を持つ?

情報利用者運営
元の映像・音声撮影中の端末で一時的に扱います。通常は動画ファイルとして保存しません。通常の撮影中は受け取りません。
暗号文ファイル撮影後に保存して保管します。通常は持ちません。所定の要請を確認して復号するときに受け取ります。
再生用秘密鍵持ちません。メールアドレスごとに保管します。
一時秘密鍵・映像の作業鍵アプリが使う間だけ扱い、ファイルには保存しません。端末からは受け取りません。復号時に作業鍵を再計算します。
公開鍵・撮影ID必要な公開情報は暗号文ファイルに入ります。鍵と撮影記録を対応させる情報を保管します。
内容の指紋・受信証明暗号文から指紋を計算でき、署名付き証明をファイルで保管します。指紋と順番・時刻を受け付け、署名して記録します。
署名用秘密鍵持ちません。運営全体の署名鍵として保管します。
署名検証用公開鍵誰でも持って構いません。このページから保存できます。公開します。現在は運営全体で同じ鍵です。
メールアドレス確認コードを受け取るために入力します。撮影の認証、鍵との対応付け、鍵紛失時の連絡に使います。

運営は鍵を持っていても、ファイルを持っていなければ、あなたの映像を再生できません。あなたがファイルを失くしたときに、運営から映像を取り寄せることもできません。

何を失くすと、何ができなくなる?

失くしたもの影響
あなたの暗号文ファイル映像を戻せません。運営の鍵や指紋だけから、映像を作り直すことはできません。別に保存した控えがあれば使えます。
運営の再生用秘密鍵その鍵で記録した映像を戻せません。同じメールアドレスで撮影した複数の記録に影響します。
運営の署名用秘密鍵同じ鍵で新しい受信証明を作れません。ただし、過去の証明は当時の公開鍵で確かめられます。再生用秘密鍵とは別なので、それだけで過去の映像まで開けなくなるわけではありません。
保存した署名検証用公開鍵以前に信頼して保存した鍵との比較ができなくなります。運営の正しい公開鍵を再確認できれば、署名を検証できます。
運営の撮影記録現在の復号プログラムはその記録との照合も必要なので、通常の復号操作ができません。鍵とファイルが残っていれば計算上は復号できますが、その復旧機能は現在提供していません。

控えが残っていれば戻せる場合があります。撮影後は暗号文をダウンロードし、ブラウザの中だけに置いたままにしないでください。

プレビューと、実際の記録

保護モードONでは、録画中のプレビューを低画質にします。条件が合う場合は、人物を黒塗りにしたプレビューを表示します。

低画質化や黒塗りは画面の表示だけです。 実際の映像は、カメラとブラウザが対応する撮影画質で暗号化して記録します。

保護モードをOFFにする場合は警告を確認し、5秒待ってから切り替わります。ONにはすぐ戻せます。

知っておいてほしいこと

復号鍵は、同じメールでの最後の撮影から1年間の保管が原則です。ただし、サービスの停止などで鍵が失われる場合もあります。利用前に確認する条件はこちら。

撮影前に配布ファイルの指紋を比べ、撮影中は一部の機能の差し替えや想定外のスクリプト挿入を検査します。変更を見つけると撮影を中断します。ただし、コンソールでの実行すべてや、拡張機能による動作すべてを検知できるわけではありません。検査報告の署名は、運営がその報告を受け取ったことを示すもので、不正や別保存がなかった証明ではありません。

運営の署名を確かめる公開鍵

これは受信証明の署名を確かめるための公開鍵です。映像を再生する鍵ではありません。誰でも保存して構いません。

「指紋」は、この公開鍵を短い値で見分けるためのものです。ファイルと別の場所に鍵や指紋を控えておけば、後で同じ鍵かを比べられます。

公開鍵の指紋(SHA-256)

9361cb5d17a30f2da91cd1ff363c88948e08a79e25fbdf7ed6a8cfa5578becf9

公開鍵

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoP3ekpG5SK/PswJ3+shAmEzUc9dg
L/vM9vVuhHSPdvj6VfPCdDEGJjrtLVaDwHh5fX9fU4PsK4YYXXa+mW93VA==
-----END PUBLIC KEY-----

このページの鍵は、公式サイトから受け取った運営の鍵として信頼するものです。ファイルに入っている鍵だけを信用せず、事前に保存した鍵と照合することが大切です。

ここで表示するのは現在の鍵です。運営が将来署名鍵を変更した場合、過去の証明には当時の公開鍵が必要です。

「鍵の保管を確認」は、何を調べる?

鍵の保管確認ページでは、スマホが毎回違う問いを出します。運営が再生用秘密鍵を使って答えに署名し、スマホがその署名を確かめます。

これにより「今、対応する秘密鍵を使える」と確認できます。昔の答えをそのまま返すだけでは通りません。将来も鍵が残っていることまで保証するものではありません。

技術名や、細かい仕組みを知りたい人へ

ここまでの説明を、実際の技術名・条件で確認できます。暗号化、署名、時刻多数決の詳細をまとめています。

詳しい技術を開く
詳しく:ECDH・HKDF・AES-256-GCMの役割

大きな映像そのものは AES-256-GCM で暗号化します。その撮影のAES鍵を作るために、公開鍵・秘密鍵を使う ECDH(P-256) と HKDF-SHA-256 を組み合わせます。ECDHは鍵共有の方式で、映像を直接暗号化する処理ではありません。

  1. メール確認後、運営がそのメールアドレス用の公開鍵を端末に渡します。運営側の対応する秘密鍵はサーバに残ります。
  2. 端末は撮影ごとに一時的な鍵の組を生成し、その秘密鍵と運営の公開鍵からECDHの共有秘密を計算します。
  3. 共有秘密、ランダムなsalt、撮影IDを含む情報から、HKDFで撮影専用のAES鍵を導出します。
  4. MediaRecorderが作る映像・音声の区間を、Worker内でAES-GCMにより暗号化し、OPFSというブラウザの保存領域へ逐次書き込みます。
  5. 復号時、運営はメールアドレス用の秘密鍵と、ファイル内にある端末の一時公開鍵から同じAES鍵を再計算します。

同じメールアドレスの運営側の鍵は、別の端末で確認しても同じものを使います。一方、一時鍵とsaltは撮影ごとに生成するため、映像のAES鍵まで全撮影で使い回すわけではありません。 メール確認は受信箱へのアクセス確認であり、実名や撮影者本人の身元確認ではありません。

暗号化には12バイトのIV(ランダムな8バイトの接頭部+4バイトの区間番号)、128ビットの認証タグを使います。撮影ID・ヘッダーハッシュ・区間番号・前区間のハッシュも認証対象に結び付けます。

詳しく:SHA-256の連鎖とECDSAの署名

ファイル先頭のヘッダーをSHA-256にした値を起点にし、「前のハッシュ+今回の区間の種類・番号・暗号文」をSHA-256にします。サーバは、区間の番号と前のハッシュのつながりを確認したうえで、撮影ID・区間番号・ハッシュ・ヘッダーハッシュ・受信時刻・時計情報を含むJSON文字列に署名します。終了時には最後の区間番号とハッシュを含む終了証明も作ります。

署名方式はECDSA、曲線はP-256、署名前のハッシュはSHA-256です。サーバのOpenSSLが作る署名はASN.1 DER形式でファイルへ保存します。ブラウザで検証するときは、Web Cryptoが扱う形式(32バイトのrと32バイトのsを連結)へ変換します。形式の変換で署名の意味が変わるわけではありません。

署名はpayload文字列そのもののUTF-8バイト列に対するものです。内容が同じに見えても、JSONを整形したり改行を追加したりすると、そのバイト列に対する署名とは一致しません。

詳しく:多数決の条件・遅延の補正・異常時の処理
  • 参照元は設定で3〜7系統、許容差は0.1〜10秒の範囲で変更できます。必要な票数は「設定数÷2の小数点以下を切り捨て、1を足す」です。4系統なら3票が必要です。
  • 名前やホスト名が違っても、同じIPアドレスの応答は別の票に数えません。ただし、別IPなら必ず運営組織やネットワークまで独立しているという保証ではありません。
  • 問い合わせは並列に行い、応答待ちは2秒です。往復が1秒を超える応答や、参照時計の不確かさが大きい応答などは採用しません。
  • 行きと帰りの通信に同程度の時間がかかると仮定して、サーバの処理時間を差し引いた通信時間の半分を補正します。測定終了のタイミングが違う各時計は、同じ比較時点へ進めてから比べます。通信時間が非対称なら誤差は残ります。
  • NTPの応答モード、バージョン、同期状態、階層(stratum)、ランダムな照会識別値の一致などを確認し、不適切な応答を除外します。この識別値は電子署名ではありません。
  • 有効な組合せのうち、最も大きく、かつ1つに決まる多数派だけを採用します。条件を満たす同人数のグループが複数あれば、曖昧なので採用しません。
  • 外部時計の収集は既定で処理終了から60秒後に再実行します。保存された参照時刻を、サーバ起動後の経過時間で現在まで進めて使います。OSのカレンダー時計をこの処理で変更しません。
  • 参照情報が180秒より古い、サーバ再起動前の情報、破損、取得不能、多数派なしの場合は、サーバ時刻に切り替えて警告を記録します。機能自体が未有効の場合は、未有効・サーバ時刻として区別します。
  • 採用元、各時計との差、通信時間、参照情報の古さ、警告などを受信時刻とともに記録します。ハッシュ受信・終了の証明では、その時計情報も運営の署名の対象です。保存するUTC時刻は秒単位で小数点以下を切り捨てます。
詳しく:受信証明の署名と違うところ

ブラウザは32バイトのランダム値(nonce)を作ります。サーバは撮影ID、nonce、確認時刻を含む識別付きメッセージに、その撮影の映像復号用秘密鍵でECDSA P-256/SHA-256の署名を作ります。対応する公開鍵の指紋も照合し、ファイルを選んだ場合は撮影時の公開鍵と一致することも確認します。サーバ側では、秘密鍵から得た公開鍵の一致と、試験用ECDH計算の一致も確認しています。

受信証明に使う運営共通の署名鍵とは別の処理です。公開鍵を公開しても秘密鍵が公開されることはありませんが、公開鍵を照合する際は何を信頼の基準にしたかが大切です。

技術一覧を開く
技術・用語役割と、この実装の設定
P-256/prime256v1公開鍵・秘密鍵の計算に使う楕円曲線。Web CryptoではP-256、OpenSSLではprime256v1という名前で扱います。ECDHとECDSAに使います。
ECDH自分の秘密鍵と相手の公開鍵から、両側で同じ共有秘密を計算する方式。端末と運営が映像の鍵を作る出発点です。
HKDF-SHA-256共有秘密から用途に合った鍵を導く方式。撮影ごとの32バイトのsaltと、撮影IDを含む用途の文字列を組み合わせ、256ビットのAES鍵を作ります。
AES-256-GCM映像を暗号化し、同時に変更を検出する認証付き暗号。256ビットの鍵と128ビットの認証タグを使います。タグは暗号化の鍵による検査値であり、運営の電子署名とは別です。
IV/nonce同じ鍵で暗号化するときに重複させない値。この実装はランダムな8バイト+区間番号4バイトの12バイトです。「鍵の保管確認」やNTPでも別用途のnonceを使います。
AAD暗号化して隠さなくても、変更されていないか検査する情報。撮影ID、ヘッダーハッシュ、区間番号、前のハッシュをAES-GCMの認証に結び付けます。
SHA-256/ハッシュの連鎖内容の指紋を作る計算。256ビットの結果を64桁の16進数で表します。前の指紋も次の計算に含め、順番のつながりを確かめます。暗号化でも電子署名でもなく、値だけで本人の身元は確認できません。
ECDSA P-256/SHA-256秘密鍵で署名し、公開鍵で検証する方式。運営共通の鍵で受信証明へ署名し、別の映像復号用の鍵で鍵所持の確認にも使います。
安全な乱数予測しにくい一時鍵、salt、IVの接頭部、nonce、撮影ID、トークン、確認コードなどを作ります。ブラウザのWeb Cryptoと、サーバのrandom_bytes/random_int、NTP収集のos.urandomを使います。
SPKI/DER/PEM/Base64url公開鍵や署名を保存・送信するための形式。SPKIは公開鍵の構造、DERはバイナリ表現、PEMはBEGIN PUBLIC KEY等を付けたテキスト表現、Base64urlはバイト列をURLで扱いやすい文字に変える表現です。これら自体は暗号化ではありません。
HTTPS/TLSブラウザとサイトの通信を保護します。映像の端末内暗号化とは別です。TLSのバージョンや暗号の組合せはWebサーバ側の設定と接続ごとに決まり、このページから一律には保証しません。対応設定ではメール送信もSMTPのSTARTTLSを使います。
確認コード・管理者認証6桁のコードは10分以内に同じセッションで確認し、回数・再送を制限します。セッション内の照合にはsalt付きSHA-256を使いますが、メール送信待ちにはコードの値が一時保存されます。管理者パスワードはpassword_hash/password_verifyによるハッシュで照合し、配布設定のハッシュ方式はbcryptです。CookieやCSRF確認なども使います。これらは受信証明の署名とは別です。

撮影用トークンやセッションとの対応の照合、メールから作る鍵の識別子などにもSHA-256を使います。メールをハッシュにした識別子は、匿名化を保証するものではありません。HKDFの内部ではHMAC-SHA-256という、鍵を使ったハッシュ計算を使います。SHA-256、HMAC、電子署名は役割が異なります。

運営側の映像復号用秘密鍵が漏れると、攻撃者が持つ対応する過去のファイルも復号され得ます。一時鍵を使う設計でも、このサービスでは運営の長期秘密鍵の漏えいから過去の映像を守る「前方秘匿性」はありません。公開鍵だけが知られても、同じことはできません。

技術者向け:指紋と署名を照合する

ダウンロードした公開鍵のファイル名には指紋が付きます。以下では、そのファイルを recryptor-receipt-public.pem へ名前変更したものとします。保存した公開鍵の指紋は次のように計算でき、表示された64桁の値と一致するか確認します。

openssl pkey -pubin -in recryptor-receipt-public.pem -outform DER | sha256sum

受信証明は payload とBase64urlの signature を持ちます。payloadの文字列をそのままのUTF-8バイト列で payload.json に保存し、signatureをBase64urlデコードしたDER署名を signature.der に保存した場合、署名だけの検証は次のとおりです。JSONの整形や末尾への改行追加はしないでください。

openssl dgst -sha256 -verify recryptor-receipt-public.pem -signature signature.der payload.json

Verified OK はそのpayloadに対する署名一致です。ファイル全体を検証するには、さらにヘッダーハッシュ・撮影ID・区間番号・暗号文から再計算したハッシュ・連鎖・終了証明を照合します。署名1つの検証だけでファイル全体の整合性が確認できたことにはなりません。

ファイルの形式

現在の拡張子は .recryptor、先頭8バイトは RCRPTR01 です。旧 .semilive と SEMLIVE1 にも対応します。古い版で撮影ごとに作った鍵は、当時のファイルに対応する鍵として扱います。

プレビューの保護

既定は長辺32画素です。予定人数が1〜9人で、人数検出・人物の黒塗り・処理速度等の条件を満たす間だけ、黒塗りした長辺128画素へ上げます。条件を満たさない場合は32画素へ戻します。人物検出には見逃しがあり、低解像度にも情報が残り得ます。

証明の範囲

外部NTP時計の多数決は第三者の署名付きタイムスタンプではなく、時刻を含む受信証明に署名するのは運営です。署名鍵の漏えいや運営による不正な署名から独立した保証はありません。端末は暗号化前の映像と暗号化用の鍵を一時的に扱います。OSのメモリやスワップ等の残留を完全に保証するものでもありません。

確認できるソースと資料

通信を調べる方法 / 暗号化Worker / 暗号処理・署名検証 / 撮影処理 / サーバ処理の公開ソース写し。公開ソース写しはリリース時の参考資料であり、サーバの稼働コードとの一致を遠隔で保証するものではありません。