2

.NET フレームワークにある XMLSerializer を使用してシリアル化するオブジェクトの HMAC を生成する必要があります。各オブジェクトには、オブジェクトの値自体のハッシュを含む「HMAC」と呼ばれるプロパティが含まれますが、「HMAC」フィールドは除外されます。CLR内の組み込みソリューションについて言及しているこの質問を見つけましたが、それが何と呼ばれているか、またはどのように使用するかについて正確には詳しく説明していませんか?

サンプル オブジェクトは次のようになります。

[Serializable]
[XmlRoot("request", IsNullable = false)]
public class Request
{

    [XmlElement(ElementName = "hmac")]
    public string Hmac { get; set; } 

    [XmlElement(ElementName = "nonce")]
    public string Nonce { get; set; }

    [XmlElement(ElementName = "expiration")]
    public DateTime Expiration { get; set; }

    /* A bunch of other properties to be serialized */

    private Request() { }

    public Request(string hmac, string nonce, DateTime expiration)
    {
        Hmac = hmac;
        Nonce = nonce;
        Expiration = expiration;
    }
}

HMAC プロパティは、HMAC オブジェクト自体を除く、オブジェクト全体のシリアル化として設定する必要があります。私が最初に考えたのは、ある種の 2 パスのシリアライゼーションを設定することです。

  1. 最初のパスで xmlignore プロパティを HMAC オブジェクトに設定する
  2. オブジェクト全体のシリアル化
  3. 結果をハッシュし、HMAC プロパティの値を設定する
  4. 全体を再シリアル化して、送信の準備をします。

これが最善の方法ですか?誰かが以前にこのようなことをしたことがありますか? そして、それを行う最もクリーンな方法であることがわかりましたか?

4

1 に答える 1

2

説明した正確な効果を得るには、2回シリアル化する必要があると思います。これを簡単にする 1 つの方法は、XmlIgnore を使用せずに、指定されたパブリック プロパティを追加することです (.NET XML シリアル化は、同様の名前のプロパティを出力するかどうかをプログラムで制御するために特別に扱います)。

 [XmlIgnore]
 public bool HmacSpecified
 {
     get { return !String.IsNullOrEmpty(this.Hmac); }
     set { }
 }

これが行うことは、hmac存在する場合にのみ XML ノードを発行することです。で同様の効果を達成できますが、DefaultValueAttributeいくつかの矛盾が見つかりました (たとえば、コンパイル中にnullで置き換えられることがあります)。""さらに、ロジックが単一の定数センチネル値よりも複雑な場合は、プロパティで処理できますが、静的属性では処理できません。

get { return !this.IsCalculatingHmac(); }

フォーマットがあなたが説明したものと正確に一致する必要がある場合、これが私が行う方法です。


出力形式に柔軟性がある場合は、メッセージ本文 (現在の XML ドキュメント) と HMAC 署名値を含むメッセージ コンテナーを使用することも検討できます。この方法では、ドキュメントを 1 回シリアル化するだけで済みます。

エンベロープがより大きなシリアライゼーション ドキュメントの一部である場合でも、エンベロープにIXmlSerializable.WriteXmlインターフェイスを実装できます。これにより、メッセージを慎重に文字列にシリアライズし、ハッシュを実行してから、HMAC とメッセージ要素をすべてXmlWriter.WriteRaw.

パフォーマンスが重要な場合、これは私が行う方法です。

于 2009-10-31T15:19:14.870 に答える