これはかなり厄介です。提案されたアプローチは、XML ドキュメントを DOM ツリーのようなものに解析し、MD5 チェックサムを見つけて、後で参照できるように保存する必要があることを暗示しているようです。次に、ドキュメントを再シリアル化して MD5 ハッシュを計算する前に、チェックサムを 0 に置き換えます。これはすべて実行可能に思えますが、潜在的にトリッキーです。私が見る主な問題は、ドキュメントの新しいシリアル化が元のものと同じではない可能性があり、属性値を一重引用符または二重引用符で囲んだり、改行を追加したり、別のエンコーディングを使用したりするなど、(XML にとって) 無関係な違いがあることです。ハッシュが異なるようにします。このルートをたどる場合は、最初にドキュメントを作成するために使用したアプリと手順が同じ選択をするようにする必要があります。この種の問題に対しては、正規の XML が標準的な解決策です (http://www.w3.org/TR/xml-c14n )。
しかし、私は何か違うことをします。運が良ければ、正規表現を記述してファイル内の MD5 ハッシュを見つけ、それを 0 に置き換えるのは非常に簡単です。これを使用してハッシュを取得し、ハッシュを再計算する前に XML ファイル内で 0 に置き換えることができます。これにより、XML ドキュメントの解析、変更、および再シリアル化で発生する可能性のあるすべての問題が回避されます。説明するために、ハッシュ '33d4046bea07e89134aecfcaf7e73015' が次のように XML ファイルに存在すると仮定します。
<docRoot xmlns='some-irrelevant-uri>
<myData>Blar blar</myData>
<myExtraData number='1'/>
<docHash MD5='33d4046bea07e89134aecfcaf7e73015' />
<evenMoreOfMyData number='34'/>
</docRoot>
(私はこれを hash.xml と呼んでいます)、MD5 を 32 個のゼロに置き換えて (ハッシュが正しいように)、perl、md5、および bash を使用したシェル コマンド ラインでの手順を示します。(これを C に翻訳することは、正規表現とハッシュ ライブラリが存在することを考えると、それほど難しくないことを願っています。)
問題を分析すると、まずファイル内にあるハッシュを見つける必要があります。
perl -p -e'if (m#<docHash.+MD5="([a-fA-F0-9]{32})#) {$_ = "$1\n"} else {$_ = ""}' hash.xml
(これは、docHash 要素の MD5 属性の開始を探し、可能な他の属性を考慮してから、次の 32 個の 16 進文字を取得することによって機能します。それらが見つかった場合は、魔法の $_ 変数でそれらをバングし、そうでない場合は設定します$_ を空にすると、$_ の値が各行に出力されます。これにより、文字列 "33d4046bea07e89134aecfcaf7e73015" が出力されます。)
次に、ファイルのハッシュをゼロに置き換えて計算する必要があります。
perl -p -e's#(<docHash.+MD5=)"([a-fA-F0-9]{32})#$1"000000000000000000000000000000#' hash.xml | md5
(ここで、正規表現はほとんど同じですが、今回は 16 進文字がゼロに置き換えられ、ファイル全体が出力されます。次に、この MD5 は、結果を md5 ハッシュ プログラムにパイプすることによって計算されます。これをビットと組み合わせると、のbashは次のようになります:
if [ `perl -p -e'if (m#<docHash.+MD5="([a-fA-F0-9]{32})#) {$_ = "$1\n"} else {$_ = ""}' hash.xml` = `perl -p -e's#(<docHash.+MD5=)"([a-fA-F0-9]{32})#$1"000000000000000000000000000000#' hash.xml | md5` ] ; then echo OK; else echo ERROR; fi
これら 2 つの小さなコマンドを実行し、出力を比較して、出力が一致する場合は "OK" を出力し、一致しない場合は "ERROR" を出力します。明らかに、これは単純なプロトタイプであり、言語が間違っています。最も単純なソリューションを示していると思います。
ところで、なぜ XML 文書内にハッシュを入れるのですか? 私が見る限り、サイド チャネルでハッシュを渡すことに比べて利点はなく (documentname.md5 という 2 番目のファイルのように単純なものであっても)、ハッシュの検証がより困難になります。