如何使用PKCS 7和SHA算法在C#中创建数字签名并验证它

问题描述:

我正在尝试对xml文档进行数字签名,并使用带有公钥和签名文档的原始xml文件验证签名。我有一个Java代码供参考。我需要Java代码转换为C#在那里我有java代码是这样的:如何使用PKCS 7和SHA算法在C#中创建数字签名并验证它

certList = new ArrayList<X509Certificate>(); 
    certList.add(signerCert); 
    certStore = new JcaCertStore(certList); 
    signedDataGenerator = new CMSSignedDataGenerator(); 
    ContentSigner sha2Signer = new JcaContentSignerBuilder("SHA512with" + privateKey.getAlgorithm()).build(privateKey); 

    ignedDataGenerator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()).setDirectSignature(true).build(sha2Signer, signerCert)); 
    signedDataGenerator.addCertificates(certStore); 
    CMSSignedData sigData = signedDataGenerator.generate(new CMSProcessableFile(inputXmlFile), false); 
    signedBytes = sigData.getEncoded(); 

我已经转换Java代码到C#是这样的:

 X509Store my = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
     my.Open(OpenFlags.ReadOnly); 
     // Find the certificate we’ll use to sign 
     RSACryptoServiceProvider csp = null; 
     foreach (X509Certificate2 cert in my.Certificates) 
     { 
      if (cert.Subject.Contains(certSubject)) 
      { 
       // We found it. 
       // Get its associated CSP and private key 
       csp = (RSACryptoServiceProvider)cert.PrivateKey;     
      } 
     } 
     if (csp == null) 
     { 
      throw new Exception("oppose no valid application was found"); 
     } 
     // Hash the data 
     SHA512Managed sha1 = new SHA512Managed(); 
     UnicodeEncoding encoding = new UnicodeEncoding(); 
     byte[] data = encoding.GetBytes(text); 
     byte[] hash = sha1.ComputeHash(data); 
     // Sign the hash 
     return csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")); 

我想将它转化,因为这两天,它正在生成符号字节数组,但无法验证。在验证它是抛出坏散列\ r \ n错误我将非常感谢任何帮助。我知道我在将java代码转换为C#时出了问题。我能够验证的代码,但仍未能签署该文件

+1

欢迎来到Stack Overflow!寻求调试帮助的问题(“为什么这个代码不工作?”)必须在问题本身中包含所需的行为,特定的问题或错误以及必要的最短代码**。没有明确问题陈述的问题对其他读者无益。请参阅:[如何创建最小,完整和可验证示例](http://*.com/help/mcve)。 –

+0

错误的散列\ r \ n是我得到的错误 –

我一直在使用System.Security.Cryptography.Pkcs库这样

public static byte[] Sign(byte[] data, X509Certificate2 certificate) 
    { 
     if (data == null) 
      throw new ArgumentNullException("data"); 
     if (certificate == null) 
      throw new ArgumentNullException("certificate"); 

     // setup the data to sign 
     ContentInfo content = new ContentInfo(data); 
     SignedCms signedCms = new SignedCms(content, false); 
     CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, certificate); 
     // create the signature 
     signedCms.ComputeSignature(signer); 
     return signedCms.Encode(); 
    } 

产生的签名和验证签名,这样

private static bool VerifySignatures(FileInfo contentFile, Stream signedDataStream) 
    { 
     CmsProcessable signedContent = null; 
     CmsSignedData cmsSignedData = null; 
     Org.BouncyCastle.X509.Store.IX509Store store = null; 
     ICollection signers = null; 
     bool verifiedStatus = false; 
     try 
     { 
      //Org.BouncyCastle.Security.addProvider(new BouncyCastleProvider()); 
      signedContent = new CmsProcessableFile(contentFile); 
      cmsSignedData = new CmsSignedData(signedContent, signedDataStream); 
      store = cmsSignedData.GetCertificates("Collection");//.getCertificates(); 
      IX509Store certStore = cmsSignedData.GetCertificates("Collection"); 
      signers = cmsSignedData.GetSignerInfos().GetSigners(); 
      foreach (var item in signers) 
      { 
       SignerInformation signer = (SignerInformation)item; 
       var certCollection = certStore.GetMatches(signer.SignerID); 
       IEnumerator iter = certCollection.GetEnumerator(); 
       iter.MoveNext(); 
       var cert = (Org.BouncyCastle.X509.X509Certificate)iter.Current; 
       verifiedStatus = signer.Verify(cert.GetPublicKey()); 
      } 

     } 
     catch (Exception e) 
     { 
      throw e; 
     } 

     return verifiedStatus; 
    } 

它正在为我工​​作