C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

外部detachedされたファイルを対象にXML電子署名

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■100366 / inTopicNo.1)  外部detachedされたファイルを対象にXML電子署名
  
□投稿者/ Angolmois (1回)-(2022/07/21(Thu) 11:14:13)

分類:[.NET 全般] 

(質問を送信したつもりがなぜか表示されない様ですので再投稿します。重複したら申し訳ありません。)


VisualStudio Pro 2017
.NET Framework 指定は 4.5でも4.6.2でも同様
実行環境は Windows 10 Pro でも Windows 7 Pro でも同様

初めて質問致します。宜しくお願いします。
外部ファイル(外部detached)を対象にXML電子署名したいと思い、その様なサンプルを探しています。

マイクロソフト社の公式ドキュメント
https://docs.microsoft.com/ja-jp/dotnet/api/system.security.cryptography.xml.signedxml.computesignature?view=dotnet-plat-ext-6.0
の3番目のサンプル、
ComputeSignature(KeyedHashAlgorithm) の説明の所にあるサンプルの事ですが、これをビルドしてみました。
(ドキュメントは.NET Framework 4.5を選択)

実行してみたところ、signedXml.ComputeSignature(Key); の行で
「Unable to resolve Uri http://www.microsoft.com.
「Uri http://www.microsoft.com を解決できません。」
という例外が発生します。

本当はネット上のURLではなくて、外部にあるファイルを対象に電子署名する実験が目的ですので、
string resourceToSign = "http://www.microsoft.com";
の行の所を、
string resourceToSign = "c:/test.txt";
としてみたのですが、同様に、
「Unable to resolve Uri C:/test.txt.」
という例外が発生しますので、自力で解決できなくて困っています。(存在するファイルです)

[他に試した事]
ファイル名を「./test.txt」「test.txt」と相対パスにしたり。

[他に試したサンプル]
https://docs.microsoft.com/ja-jp/dotnet/api/system.security.cryptography.xml.reference.uri?view=netframework-4.5
のサンプルと
https://docs.microsoft.com/ja-jp/dotnet/api/system.security.cryptography.xml.signedxml.addreference?view=dotnet-plat-ext-6.0
の2番目のサンプルで、いずれも同様の結果になります。

[知りたい事]
ReferenceタグのURIに外部ファイルを指定して署名するにはどの様にしたら良いでしょうか。
何か足りない事があるのだと思います。
皆様にご教示頂きたいと存じます。宜しくお願いします。


Angolmois

引用返信 編集キー/
■100367 / inTopicNo.2)  Re[1]: 外部detachedされたファイルを対象にXML電子署名
□投稿者/ Hongliang (1247回)-(2022/07/21(Thu) 13:13:08)
https://support.microsoft.com/en-us/topic/after-you-apply-security-update-3141780-net-framework-applications-encounter-exception-errors-or-unexpected-failures-while-processing-files-that-contain-signedxml-922edd45-a91e-c755-bb30-2604acf37362

既定で無効化されるようになったようです。
XPathとXSLTによって計算量を増大させサービス拒否攻撃を引き起こすことが可能であるからとのこと。
この分野は詳しくないので私にはよくわかりませんが。
リンク先にはレジストリの設定で可能にさせることができることが案内されています。

あるいは、new Reference(Stream)コンストラクタを使うことで直接署名対象を指定することもできます。
引用返信 編集キー/
■100368 / inTopicNo.3)  Re[2]: 外部detachedされたファイルを対象にXML電子署名
□投稿者/ Angolmois (2回)-(2022/07/21(Thu) 14:14:21)
Hongliangさん、レスありがとうございました。
教えて頂いたURLも見ました。

レジストリの設定も変更してみて、手元の環境ではうまくいかない様でしたが、もう少し調べて色々試してみます。
new Reference(Stream)コンストラクタの件も調査してみます。
またここに報告致します。

ご教示頂いてありがとうございました。

引用返信 編集キー/
■100370 / inTopicNo.4)  Re[3]: 外部detachedされたファイルを対象にXML電子署名
□投稿者/ Angolmois (3回)-(2022/07/21(Thu) 15:30:36)
Hongliangさんのレスの
> new Reference(Stream)コンストラクタを使うことで直接署名対象を指定することもできます。
のアドバイスによって、署名の部分については解決しました。
ありがとうございました!

具体的は変更は下記です。
// Create a reference to be signed.
// 修正後▽
FileStream urifs = new FileStream(URIString, FileMode.Open);
Reference reference = new Reference(urifs);
// 以下は修正前
// Reference reference = new Reference();
// ここまで△

// Add the passed URI to the reference object.
reference.Uri = URIString;

// Add the reference to the SignedXml object.
signedXml.AddReference(reference);

// Compute the signature.
signedXml.ComputeSignature(Key);

// 行追加▽
urifs.Close();
// ここまで△

上記でうまく署名後のXMLが出来ましたが、新たな問題が発生してしまいました。

同じサンプルの中に署名の検証部分がありまして、そのサンプルの最後の部分
signedXml.CheckSignature(Key)
の所で、同様の例外「Uri test.txt を解決できません」が発生してしまいます。
(test.txtが存在する場所をカレントディレクトリとして実行)

これはどの様に解決したら良いでしょうか。

恐らく、検証の時にも Reference(Stream) をするのだと思いますが、そのReferenceオブジェクトをどう指定したら良いのか、という観点で色々探してみましたが、自分では解決できませんでした。
ご教示の程、宜しくお願い致します。

引用返信 編集キー/
■100392 / inTopicNo.5)  Re[4]: 外部detachedされたファイルを対象にXML電子署名
□投稿者/ Hongliang (1249回)-(2022/07/24(Sun) 23:30:34)
全く詳しくないので、コードいじくって何となくできた程度ですが

一旦SignedXmlにLoadXmlしたあと、.SignedInfo.ReferencesをClear
new Reference(Stream)して、署名XMLからReference要素を取ってきてReferenceオブジェクトにLoadXml
AddReference

でそれっぽく動いているようには見えます。
こういうコーディングが妥当かどうかは存じません。
引用返信 編集キー/
■100394 / inTopicNo.6)  Re[5]: 外部detachedされたファイルを対象にXML電子署名
□投稿者/ Angolmois (4回)-(2022/07/25(Mon) 10:24:58)

> 全く詳しくないので、コードいじくって何となくできた程度ですが

Hongliang さん、
なんと! 色々試して頂いてありがとうございます。
私の方でも試してみます。
とり急ぎお礼まで。

Angolmois

引用返信 編集キー/
■100395 / inTopicNo.7)  Re[6]: 外部detachedされたファイルを対象にXML電子署名
□投稿者/ Angolmois (5回)-(2022/07/25(Mon) 15:12:27)
2022/07/25(Mon) 16:02:00 編集(投稿者)
2022/07/25(Mon) 16:01:15 編集(投稿者)

No100394 (Angolmois さん) に返信

Hongliangさんのレスによって、検証の問題も解決しました!

具体的は変更は下記で、サンプルの最後の
return signedXml.CheckSignature(Key);
の1行を下記の様に修正します。
------------
// Signature の SignedInfo を得る
SignedInfo signedinfo = signedXml.SignedInfo;

// Signature の SignedInfo の Reference を得る
ArrayList refs = signedinfo.References;
Reference ref1 = (Reference)refs[0];
// 本当はReferenceは複数ありうるが、
// ここでは最初の一つ(0)であると決めつけている事に注意

// 問題の Reference のURIとダイジェスト値を得る
string urio = ref1.Uri;
byte[] dvo = ref1.DigestValue;

// urioの相対パスが合う様に事前にカレントディレクトリを移動する事が必要

// URIを読み込む
FileStream urifs = new FileStream(urio, FileMode.Open);

// 本当はここで
// 署名対象ファイル(URI)のダイジェスト値を自分で計算して
// dvoと比較すべきであるが、取り急ぎ省略

// 問題の Reference のXML要素を得る
XmlElement elemRef = ref1.GetXml();

// 新たなReferenceを作る
Reference reference = new Reference(urifs);
reference.Uri = urio;

// ReferenceオブジェクトにXML要素をLoadXmlする
reference.LoadXml(elemRef);

// Referenceを全て削除する
refs.Clear();

// 新たに作ったReferenceをaddする
signedXml.AddReference(reference);
// 本当は複数ありうるので
// その全部を順番にAddReferenceするのが必要と思う

// Check the signature and return the result.
Boolean bR = signedXml.CheckSignature(Key);
urifs.Close();
return bR;
------------


ちなみに、refs.RemoveAt() をして
新たなReferenceを refs.Insert() する事も考えましたが、
実際に試してみたところ、検証の時に
Object reference not set to an instance of an object.
という例外が発生しました。
AddReference() でないとダメな様です。


Hongliangさん、
そして答えを考えて下さった方々、
ありがとうございました!


[余談]
C++の話ならば自分も回答ができるかと思ったのですが、
皆さん、回答が素早いですね!
自分が気づいた時には解決してしまっています。

当掲示板に恩返しができる様に精進します。

Angolmois

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ