5

メソッドの文字列パラメーターとして XML ドキュメントを受け取ります。XML ドキュメントは次のとおりです。   

<Document>
    <ZipContainer> Zip_File_In_Base64 </ZipContainer>
    <X509Certificate> Certificate_In_Base64 </X509Certificate>
</Document>

この文字列から、base64 形式の ZIP ファイルと base64 形式の X509Certificate2 証明書を抽出します。ZIP ファイルには以下が含まれます。

  • ZIP ファイルの内容を XML として記述したファイル (ファイルpackageDescription.xml)。

  • 送信されたドキュメントの内容を含むファイル (たとえば、*.docファイル);

  • 分離デジタル署名のコンテンツを含むファイル (*.p7sファイル - 分離デジタル署名);

アーカイブから、文書に署名した署名を抽出する必要があります (分離されたデジタル署名は複数の場合があります)。分離されたデジタル署名は、.p7s拡張子を持つファイルに保存されます。各署名は、ユーザーがポータルにログインするデジタル署名との一致を確認するために実行する必要があります。

は次の 2 つのステップで構成されている必要があります。

  1. メソッドを参照してくださいcertificateValidator()(以下のこのメソッドを参照してください): これは分離された署名であり、署名された.p7s対応するファイルを含むファイルに含まれています。これらの *. P7s ファイル。
    例: 関連ファイルのペア:ZayavUL_3594c921f545406d9b8734bbe28bf894.doc_1.p7s
    ZayavUL_3594c921f545406d9b8734bbe28bf894.doc.

  2. メソッドを参照してください: これは、XML ドキュメントの入力文字列から抽出された証明書を使用してcertificateValidator()、ファイルの証明書を検証します。.p7s

質問

  1. メソッドsignatureValidator(以下のこのメソッドを参照) は現在使用されていません.p7s。私は試みましたが、成功しませんでした。.p7s対応するファイルの分離されたファイルの署名を正しく検証するにはどうすればよいですか?

  2. メソッドcertificateValidator(以下のこのメソッドを参照) では、.p7sファイルから抽出された証明書と、Base64 形式の入力文字列から抽出された証明書との適合性をどのように検証すればよいですか?

  3. コード行foreach (X509Certificate2 x509 in signCms.Certificates) { }---> Certificates Collection は常に空です。なんで?

入力パラメータ

  • Dictionary <string, byte[]> dictP7SFiles(キー - ファイルの名前 *.p7s、値 - *.p7s ファイルを表すバイト配列)

  • Dictionary <string, byte[]> dictNotP7SFiles(キー - *.p7s ファイルから分離された署名を使用して署名されたファイルの名前、値 - ファイルを表すバイト配列)

  • X509Certificate2 userCertX509- 入力 xml-document から抽出された証明書オブジェクト (Base64 形式の場合)

コード

以下は、検証手順の実装のテストです (上記の 2 つの手順を参照)。

private bool certificateValidator(Dictionary<string, byte[]> dictP7SFiles, 
    Dictionary<string, byte[]> dictNotP7SFiles, X509Certificate2 userCertX509)
{
  bool isValid = false;           
  try
  {               
    foreach (KeyValuePair<string, byte[]> pair in dictP7SFiles)
    {
      ContentInfo contentInfo = new ContentInfo(pair.Value);
      SignedCms signCms = new SignedCms(contentInfo, true);                   

      if (signCms.Certificates.Count != 0)
      {
        //Certificates Collection always is empty. Why?
        foreach (X509Certificate2 x509 in signCms.Certificates)
        {
          if ((x509.SerialNumber != userCertX509.SerialNumber) 
              || (x509.Thumbprint != userCertX509.Thumbprint))
          {
            isValid = false;
            return isValid;
          }
        }

        isValid = true;
        return isValid;
      }
    }
  }
  catch (Exception ex)  
  {
    //here process exception code
  }           

  return isValid;
}



private bool signatureValidator(Dictionary<string, byte[]> dictP7SFiles, 
    Dictionary<string, byte[]> dictNotP7SFiles, X509Certificate2 userCertX509)
{
  bool isValid = false;
  try
  {              
    byte[] data = dictP7SFiles["ZayavUL_3594c921f545406d9b8734bbe28bf894.doc"];
    byte[] publicKey;
    byte[] signature;
    object hasher = SHA1.Create(); // Our chosen hashing algorithm.
    // Generate a new key pair, then sign the data with it:
    using (var publicPrivate = new RSACryptoServiceProvider())
    {
      signature = publicPrivate.SignData(data, hasher);
      publicKey = publicPrivate.ExportCspBlob(false); // get public key
    }
    // Create a fresh RSA using just the public key, then test the signature.
    using (var publicOnly = new RSACryptoServiceProvider())
    {
      publicOnly.ImportCspBlob(publicKey);

      isValid = publicOnly.VerifyData(data, hasher, signature); // Return True

      //isValid = ByteArrayCompare(dictP7SStreams["ZayavUL_3594c921f545406d9b8734bbe28bf894.doc_1.p7s"], signature);

      byte[] p7sDetachedSignature = File.ReadAllBytes(@"D:\ZayavUL_3594c921f545406d9b8734bbe28bf894.doc_1.p7s");
      isValid = ByteArrayCompare(p7sDetachedSignature, signature);
    }                
  }
  catch (Exception)
  {
    //here process exception code
  }

  return isValid;    
}
4

1 に答える 1

0

あなたが間違っている主なことは、CMS と署名を再生成することです。CMS メッセージを解析してから、検証中に外部コンテンツを示す必要があります。

  1. 対応するファイルの .p7s ファイルの切り離された署名を正しく検証するにはどうすればよいですか?

SOの次の Java コードを見て、署名を検証する方法を確認してください。C# は同じアーキテクチャを使用する必要があるため、同様に機能するはずです。

  1. メソッド certificateValidator (以下のこのメソッドを参照) で、.p7s ファイルから抽出された証明書と、Base64 形式の入力文字列から抽出された証明書との適合性を確認するにはどうすればよいですか?

Base 64 証明書をデコードし、証明書のチェーン検証と検証を実行します。どの程度の検証を実行するか (発効日の確認など) は、あなた次第です。

  1. コード行 foreach (X509Certificate2 x509 in signCms.Certificates) { } ---> Certificates Collection は常に空です。なんで?

新しい CMS 構造の構築中に 1 つを入れなかっただけです。


署名を再生成するべきではありません。通常、検証中に秘密鍵を取得することはなく、アルゴリズムが CMS ドキュメント内で使用されているものと一致しない場合があります。さらに、たとえそうであったとしても、署名の生成は常に決定論的であるとは限りません (異なる署名値が得られる可能性があります)。

于 2015-10-02T09:42:29.127 に答える