C# で DSA 署名を検証するにはどうすればよいですか?
与えられた:
- メッセージテキスト、
- 署名付きダイジェスト (通常は ASN.1 DER 形式)、
- 公開鍵 (署名付き X.509 証明書、PEM または DER 形式)
いくつかのアプローチを試しましたが、成功しませんでした:
OpenSSL.NET :ライブラリに関するさまざまな奇妙なエラー。SourceForge で作成者と一緒に開いているスレッドを実行していますが、まだ解決できていません。
Microsoft .NET API:比較のために DER 署名を解凍できません。DSA 署名は 40 バイト (2 つの 20 バイト整数) ですが、DER でエンコードされた 2 つの整数のシーケンスとして提示されるため、合計の長さは 46 から 48 バイトの範囲になります (簡単な概要については、この投稿を参照してください)。 NET には、ASN.1/DER を解析するためのコードが含まれています (証明書を DER 形式で読み取ることができるため)。コードは深く埋もれており、アクセスする方法がないため、ASN.1/DER でエンコードされた sig から 40 バイトを正しく取得できます。 . この問題は私を次の選択肢に導きました...
BouncyCastle:関数を使用して
Org.BouncyCastle.Asn1
、ASN.1 署名を解析し、それをコンポーネントの R および S 整数値に取り込むことができます。しかし、これらを署名検証ルーチンに渡すと、説明がなく失敗します。C# API は完全に文書化されておらず、Java のバージョンはほとんど文書化されていないため、私が何か間違ったことをしているのかどうかはわかりません (しかし、私が見つけることができる例や HOWTO 情報はありません)。
私は約1週間、この問題に身を投じてきました。誰かが以前にそれをやったに違いないことは知っていますが、完全な/実用的な例は見つかりませんでした.
ここには 3 つの C# プロジェクトがあり、それぞれ 95% 完了していますが、失敗の原因となる重大な欠陥が 1 つあります。動作するサンプルコードは非常に高く評価されます。
編集:これは、私が検証しようとしている署名の例で、Base64 と ASCII 16 進数に変換して投稿可能にしています。この特定のものは 47 バイトですが、適切なパーサーはそれを受け入れる必要があります。詳細については、DER 仕様を参照してください (BER/DER は、MSB が 1 の場合に符号を確認するために先頭に 00 を追加します)。
Base64: MC0CFQCUgq2DEHWzp3O4nOdo38mDu8mStwIUadZmbin7BvXxpeoJh7dhquD2CTM=
ASCII Hex: 302d0215009482ad831075b3a773b89ce768dfc983bbc992b7021469d6666e29fb06f5f1a5ea0987b761aae0f60933
構造は DER 仕様に準拠しています。次のように解析します。
30 2d: sequence, length 45 (may vary from 44 to 46)
02 15: integer, length 21 (first byte is 00 to confirm sign)
009482ad831075b3a773b89ce768dfc983bbc992b7
02 14: integer, length 20 (leading 00 not necessary for this one)
69d6666e29fb06f5f1a5ea0987b761aae0f60933
独自の DER パーサーを作成することは実際にはオプションではありません。エラーの余地が多すぎるため、これを適切に行う方法が必要です。