首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >验证分离签名(*.p7s文件)和X509Certificate2

验证分离签名(*.p7s文件)和X509Certificate2
EN

Stack Overflow用户
提问于 2012-09-02 22:42:57
回答 1查看 4.5K关注 0票数 5

在我的方法中,我接收作为字符串参数的XML文档。XML文档是:

代码语言:javascript
运行
复制
<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扩展名的文件中。必须对每个签名进行检查,以检查其与数字签名的协议,用户使用数字签名登录门户。

必须包括两个步骤:

  1. 请参见方法certificateValidator() (请参阅下面的方法):这是一个独立的签名,包含在.p7s文件中,其中有相应的文件被签名,这些*。P7s-档案。 例如:一对相关文件:ZayavUL_3594c921f545406d9b8734bbe28bf894.doc_1.p7sZayavUL_3594c921f545406d9b8734bbe28bf894.doc
  2. 请参见方法certificateValidator():使用从提取的证书验证来自文件.p7s的证书。

问题

  1. 方法signatureValidator (请参阅下面的方法)目前没有使用文件.p7s的分离签名。我试过了,但没有成功。如何正确验证.p7s文件对其相应文件的分离签名?
  2. 在方法certificateValidator (请参阅下面的方法)中,如何验证从.p7s文件提取的证书与从Base64格式的输入字符串中提取的证书的一致性?

  1. 代码foreach (X509Certificate2 x509 in signCms.Certificates) { } ->证书集合的行始终是空的。为什么?

输入参数

  • Dictionary <string, byte[]> dictP7SFiles (键-文件名*.p7s,字节值数组,表示*.p7s文件)
  • Dictionary <string, byte[]> dictNotP7SFiles (键-使用*.p7s文件的分离签名、字节值数组、表示文件的文件的名称)
  • X509Certificate2 userCertX509 -证书对象,从输入的xml-文档中提取(其中它具有Base64格式)

代码

下面是对验证步骤的实现的测试(见上面的这两个步骤):

代码语言:javascript
运行
复制
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;    
}
EN

回答 1

Stack Overflow用户

发布于 2015-10-02 09:42:29

您所做的主要错误是重新生成CMS和签名。您应该解析CMS消息,然后在验证期间指示外部内容。

  1. 如何正确验证.p7s文件对其相应文件的分离签名?

看看following Java code on SO,看看如何验证签名;C#应该使用相同的体系结构,因此它的工作方式应该是类似的。

  1. 在方法certificateValidator (请参阅下面的方法)中,如何验证从.p7s文件提取的证书与从Base64格式的输入字符串中提取的证书的一致性?

解码基本64证书,并执行证书的链验证和验证。要执行多少验证(例如检查生效日期)取决于您。

  1. 代码foreach (X509Certificate2 x509 in signCms.Certificates) {}-->证书集合始终为空。为什么?

在建造新CMS结构的过程中,你根本没有放进去。

当然,您也不应该重新生成签名。通常,在验证期间您将没有私钥,并且算法可能与CMS文档中使用的算法不匹配。此外,即使是这样,签名生成也并不总是确定性的(您可能得到不同的签名值)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12240355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档