2011-01-12 26 views
44

次の質問は、最初に思われるより複雑です。JSONオブジェクトを暗号化する方法

私は任意のJSONオブジェクトを持っているとします。その中には、他のネストされたJSONオブジェクトを含む任意の量のデータが含まれているものとします。私が望むのは、実際のJSONフォーマット自体に関係なく、JSONデータの暗号化ハッシュ/ダイジェストです(例えば、改行やJSONトークンの間隔の違いを無視するなど)。

JSONはさまざまなプラットフォームのさまざまな(デ)シリアライザによって生成/読み込まれるため、最後の部分が必要です。デシリアライズ時にデータを読み込むときに書式設定を完全に削除するJava用のJSONライブラリが少なくとも1つはわかっています。そのようにして、ハッシュを破ります。

上記の任意のデータ節は、特定の順序で既知のフィールドを取得してハッシングする前にそれらを連結することを妨げるため、事を複雑にします(Javaの非暗号化hashCode()メソッドの仕組みを大まかに考える)。

最後に、JSON文字列全体をハッシュ演算する際に無視する必要があるフィールドがあるため、(逆シリアル化の前に)バイトチャンクとしてハッシュするのは好ましくありません。

私はこの問題の良い解決策があるか分からないが、私は=任意のアプローチや感想をお待ちしており)

+3

あなたの名前がどのように問題になっているか気づくことはできません。 –

+1

あなたはXML DSigを見ましたか?彼らは同じ問題を抱え、非常に複雑な "標準化"仕様を持っています。 – mtraut

+5

これは標準化されています。 JSON Web Signature(JWS)ドラフトRFCを参照してください。 http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-17 – user239558

答えて

38

問題は、柔軟性が許されている任意のデータ形式に対してハッシュを計算するときに共通の問題です。これを解決するには、が正規表現の表記を必要とします。

例えば、Twitterやその他のサービスで認証に使用されるOAuth1.0aプロトコルは、要求メッセージの安全なハッシュを必要とします。ハッシュ値を計算するには、まずフィールドをアルファベット順に区切り、改行で区切り、フィールド名を削除して、空の値に空行を使用する必要があると言います。署名またはハッシュは、その正規化の結果に基づいて計算される。

XML DSIGは同じ方法で動作します。署名する前にXMLを標準化する必要があります。 proposed W3 standard covering thisがあります。なぜなら、それは署名のための基本的な要件であるからです。一部の人々はそれをc14nと呼んでいます。

jsonの正規化標準についてはわかりません。それは研究価値がある。

もし存在しない場合は、特定のアプリケーションの使用法を確立することができます。合理的なスタートは次のようになります。

  • 辞書順名前
  • によってすべての名前
  • 上のすべての文字列名の間に、
  • スペースなし、または1スペースを値に使用され、二重引用符を使用し、二重引用符をプロパティを並べ替えますそして、コロン、コロンと値
  • の間の値と、次のコンマ
  • の間にはスペースを他のすべての空白は単一のスペースまたは何もどちらかに崩壊しない - 1
  • 01を選択してください

あなたはまた、どのように考えてもよいでしょう、あなたの選択したアルゴリズムで(一例がある署名自体保持プロパティ)あなたが署名する必要はありません

  • 記号結果を、任意のプロパティを除外その署名をJSONオブジェクトに渡すことができます。おそらく、 "nichols-hmac"などのよく知られたプロパティ名を設定して、base64でエンコードされたハッシュのバージョンを取得します。このプロパティは、ハッシュアルゴリズムによって明示的に除外される必要があります。 JSONの受信者は、ハッシュをチェックすることができます。

    正規表現は、アプリケーションで渡した表現である必要はありません。任意のJSONオブジェクトがあれば簡単に作成する必要があります。

  • +2

    正規化では文字の表現も考慮する必要があります: '" A "' vs '" \ 「u0041」、「」、「vs」、「u00e9」、「vs」、「u00E9」です。数字についても同じ問題があります: '1'対' 0.1e1'。 – dolmen

    +1

    など。 https://github.com/jchris/canonical-json – opyate

    +2

    これをチェックしてください:https://github.com/substack/json-stable-stringify – jbaylina

    0

    私は(アルファベット順例えば)指定されたために、すべてのフィールドを行うだろう。なぜ恣意的なデータが違いますか?あなたはプロパティを繰り返し処理することができます(ala reflection)。

    また、未処理のjson文字列をいくつかの明確に定義された標準形式(すべての超流動形式を削除する)に変換することを検討し、それをハッシュします。

    5

    独自のJSON正規化/正規化を作成する代わりに、bencodeを使用すると便利です。意味的には、JSON(数字、文字列、リスト、および辞書の構成)と同じですが、暗号化ハッシュに必要な明確なエンコーディングの特性を備えています。

    トレントファイル形式としてbencodeが使用されていますが、すべてのビットトレントクライアントに実装が含まれています。

    +0

    ほぼすべての言語にオブジェクト(デ)シリアライズを行うためのライブラリが用意されているため、JSONが非常に好ましいです。 –

    +4

    私は、ハッシュ化前の正規化ステップとしてのみbencodeを使用することを意味しました。あなたのハッシングルーチン以外は、すべてJSONのままです。 –

    +0

    bencodeは優れており、実装が非常に簡単です。 Canonical JSONは、標準のJSONパーサーとも解析しません。ハッシュ関数の入力だけを必要とするこのアプリケーションでは解析する必要はありません。 – joeforker

    2

    JSON-LDは標準化を行うことができます。

    コンテキストを定義する必要があります。

    3

    これは、S/MIMEシグネチャとXMLシグネチャの問題を引き起こすのと同じ問題です。すなわち、署名されるべきデータの複数の等価な表現が存在する。 JSONで例えば

    { "Name1": "Value1", "Name2": "Value2" } 
    

    { 
        "Name1": "Value\u0031", 
        "Name2": "Value\u0032" 
    } 
    

    またはあなたのアプリケーションに応じて、これはさえ相当することがあります。

    { 
        "Name1": "Value\u0031", 
        "Name2": "Value\u0032", 
        "Optional": null 
    } 
    

    正規化は、その問題を解決することができ、しかし、それはまったく必要のない問題です。

    仕様を制御できるのは、オブジェクトを「同等の」異なる表現に変換されないようにするために、何らかの種類のコンテナにラップすることです。

    I.e. "論理的な"オブジェクトに署名するのではなく、その代わりに特定のシリアライズされた表現に署名することで、この問題を回避してください。

    たとえば、JSONオブジェクト - > UTF-8テキスト - >バイト。バイトをバイトとして署名し、をバイトとして送信します。ベース64エンコーディング。あなたがバイトに署名しているので、空白のような違いは署名されたものの一部です。

    代わりにこれをやろうとしているの:

    { 
        "Base64JSONContent": "eyAgIk5hbWUxIjogIlZhbHVlMSIsICJOYW1lMiI6ICJWYWx1ZTIiIH0s", 
        "Signature": "asdflkajsdrliuejadceaageaetge=" 
    
    } 
    

    すなわち:

    { 
        "JSONContent": { "Name1": "Value1", "Name2": "Value2" }, 
        "Signature": "asdflkajsdrliuejadceaageaetge=" 
    } 
    

    はちょうどこの操作を行いますJSONに署名しないでください。符号化された JSONのバイトであるに署名してください。

    はい、署名はもはや透過的ではありません。

    +0

    Pro:これは、「オプション」オブジェクトによって示されるように、プロパティの結合を緩めます。 マイナーコンシール:標準APIツールではこのパッケージを理解できません。そして再び、それらのハッシュを生成することは自明ではありません。 – LexieHankins

    +1

    私はこの問題に焦点を当ててから数年が経ちましたが、今日、ハッシュを実装しなければならない場合は、これが私のアプローチです。 –

    関連する問題