お客様のデータについての証拠に署名するサービスには、わかりやすい誘惑があります:データを証拠の中に入れてしまうことです。そうすれば検索もサポートも楽になり、より充実したダッシュボードも作れるでしょう。当社は早い段階で、Trustviceのレシートはそうしないと決めました:レシートが持つのは、記述する対象のハッシュであって、コンテンツではありません。
この記事では、その理由と、お客様自身の協力なしには設計の保護が及ばなくなる場面をご説明します。
持ち運ばれる証拠#
レシートが役に立つのは、誰かに渡せる場合だけです:監査人、相手方、調停人。その中身は、渡した相手なら誰でも読めます。レシートがコンテンツを持っていたら、共有するたびに何かが漏れることになり、そのつど墨消しを考えなければなりません。
SHA-256ハッシュなら、それを避けられます。64文字の16進数で、コンテンツの正確なバイト列を、それを明かすことなく特定します。するとレシートは、実質的にこう述べることになります:この時刻に、このラベルのもとで、これらのバイト列が提示された。バイト列はお客様の手元に残ります。必要なときにそれを提出すれば、誰でもハッシュ化でき、そのハッシュはレシートと一致するか、しないかのどちらかです。
ハッシュ化だけでは足りない場面#
ここで話を終えれば、お客様を誤解させることになります。ハッシュがコンテンツをよく守るのは1つの条件のもとでだけであり、レシートのいくつかのフィールドはそもそもハッシュではありません。
ハッシュがコンテンツを隠せるのは、コンテンツが予測できない場合だけ#
SHA-256は逆算できませんが、推測はできます。入力の可能性が少ない場合、たとえば「はい」か「いいえ」の回答、メールアドレス、短いコード、既知のテンプレートなどであれば、レシートを持つ誰もが候補をハッシュ化して比較できます。そうしたコンテンツでは、ハッシュ化する内容にランダムな値、つまりノンスを含め、そのノンスを原本と一緒に保管してください。そうすればレシートは、読み手に推測させることなく、存在を証明できます。
平文で書き込まれるフィールドもある#
お客様が選ぶラベルやその他の自由記述フィールドは平文で書き込まれ、いったんレシートに署名されるとそのまま残ります。注文番号や内部IDなどの不透明な識別子を使い、対応表はお客様の側で保管してください。
正確なバイト列をハッシュ化する#
ハッシュが特定するのはバイト列であって、意味ではありません。末尾の改行、\nの代わりの\r\n、異なるUnicode正規化は、いずれも別のハッシュになります。テキストの場合は、エンコーディングと改行コードを一度決めて、それを守ってください。構造化されたレコードの場合は、再シリアライズしたものではなく、ハッシュ化した正確なバイト列を保存してください:後でキーの順序が異なるJSON.stringifyを行えば、別のハッシュになります。複数のファイルの場合は、各ファイル自身のハッシュを列挙したマニフェストをハッシュ化し、そのマニフェストを証明してください。
原本を保管する#
一つの帰結に備えてください:レシートはコンテンツを再現できません。 原本を失っても、レシートは引き続き検証できますが、お客様が提示できる文書について有用なことは何も証明しなくなります。原本は追記専用のストレージに、レシートと並べて保管してください。
削除と、証拠というものの性質#
どんな設計でも取り除けない限界があります。すでに誰かに渡したレシートは、当社が何をしても、その相手が検証し続けることができます。検証に必要なのはレシートと公開鍵だけだからです。それこそが、レシートを証拠たらしめる性質です。そしてそれが、上の助言が重要である理由でもあります:個人データを平文のフィールドに入れないようにしておけば、レシートの消去という問題が難しくなることはまずありません。レシートはハッシュしか持たないため、通常はお客様自身の保管庫で原本を消去すれば十分です。
まとめ#
当社が署名するのはお客様のデータについての事実であって、データそのものではありません。まずハッシュ化するからこそ、レシートは持ち運べ、検証に当社のストレージへの信頼が必要になることもありません。ただし、推測可能な値を秘匿するものではなく、平文フィールドに書いた内容を守るものでもありません。小さな入力にはノンスを、ラベルには不透明なIDを使い、原本は保管しておいてください。
詳しくはレシートが証明すること、しないことと当社のセキュリティページをご覧ください。
