2015-11-17 23 views
4

我使用下面的腳本驗證Digitaly簽署XML總是假

sn.exe -k KeyFile.snk 
sn.exe -m y 
sn.exe -i KeyFile.snk test 

然後我用它來驗證和使用下面的代碼簽名我的XML snipet

private void SignXml(XmlDocument xmlDoc) 
    { 

     CspParameters parms = new CspParameters(1);   // PROV_RSA_FULL 
     parms.Flags = CspProviderFlags.UseMachineKeyStore; // Use Machine store 
     parms.KeyContainerName = "test";    // "CodeProject" container 
     parms.KeyNumber = 2;        // AT_SIGNATURE 
     RSACryptoServiceProvider csp = new RSACryptoServiceProvider(parms); 

     // Creating the XML signing object. 
     SignedXml sxml = new SignedXml(xmlDoc); 
     sxml.SigningKey = csp; 

     // Set the canonicalization method for the document. 
     sxml.SignedInfo.CanonicalizationMethod = 
      SignedXml.XmlDsigCanonicalizationUrl; // No comments. 

     // Create an empty reference (not enveloped) for the XPath 
     // transformation. 
     Reference r = new Reference(""); 

     // Create the XPath transform and add it to the reference list. 
     r.AddTransform(new XmlDsigEnvelopedSignatureTransform(false)); 

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

     // Compute the signature. 
     sxml.ComputeSignature(); 

     // Get the signature XML and add it to the document element. 
     XmlElement sig = sxml.GetXml(); 
     if (xmlDoc.DocumentElement != null) 
      xmlDoc.DocumentElement.AppendChild(sig); 

    } 
    public static Boolean VerifyXml(XmlDocument doc) 
     { 

      // Get the XML content from the embedded XML public key. 
      Stream s = null; 
      string xmlkey = string.Empty; 
      try 
      { 
       s = typeof(Program).Assembly.GetManifestResourceStream(
        "LicenceVerifier.PubKey.xml"); 

       // Read-in the XML content. 
       StreamReader reader = new StreamReader(s); 
       xmlkey = reader.ReadToEnd(); 
       reader.Close(); 
      } 
      catch (Exception e) 
      { 
       Console.Error.WriteLine("Error: could not import public key: {0}", 
        e.Message); 
       return false; 
      } 

      // Create an RSA crypto service provider from the embedded 
      // XML document resource (the public key). 
      RSACryptoServiceProvider csp = new RSACryptoServiceProvider(); 
      csp.FromXmlString(xmlkey); 

      // Create the signed XML object. 
      SignedXml sxml = new SignedXml(doc); 

      try 
      { 
       // Get the XML Signature node and load it into the signed XML object. 
       XmlNode dsig = doc.GetElementsByTagName("Signature", 
        SignedXml.XmlDsigNamespaceUrl)[0]; 
       sxml.LoadXml((XmlElement)dsig); 
      } 
      catch 
      { 
       Console.Error.WriteLine("Error: no signature found."); 
       return false; 
      } 

      // Verify the signature. 
      if (sxml.CheckSignature(csp)) 
       return true; 
      else 
       return false; 

問題創建一個鍵值驗證總是返回false,即使我使用密鑰的公鑰,任何想法如何解決,簽名部分看起來像:

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> 
    <SignedInfo> 
     <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /> 
     <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /> 
     <Reference URI=""> 
     <Transforms> 
      <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> 
     </Transforms> 
     <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> 
     <DigestValue>XT/TOXNZ6SEe6V3c6Ulxa/rOzLE=</DigestValue> 
     </Reference> 
    </SignedInfo> 
    <SignatureValue>t1C/ycVh/8nV1uvc9WKbOTawKQjg3luUi7717AQDHc4N+g7DDHYHAb2zvoSEUTCHIkY9UFenoZqjbLwL9/ejyef/kQe8V/jrj0GZ60BNp8ee0nXSfr91wEdhOo9qqSo/iPbnP8By9tJnbOcJG7EFWjorgMITfHGct4QXfMZFoh4=</SignatureValue> 
    </Signature> 

我用他們喜歡

SignXml(xmlDoc); // where xmlDoc is the xmldocument i create to be signed 
///////////////// TO Verify ////////////// 
      try 
      { 
       // Create a new CspParameters object to specify 
       // a key container. 

       Console.WriteLine("Type path"); 
       var path = Console.ReadLine(); 

       // Create a new XML document. 
       XmlDocument xmlDoc = new XmlDocument(); 

       // Load an XML file into the XmlDocument object. 
       xmlDoc.PreserveWhitespace = true; 
       xmlDoc.Load(path); 

       // Verify the signature of the signed XML. 
       Console.WriteLine("Verifying signature..."); 
       bool result = VerifyXml(xmlDoc); 

       // Display the results of the signature verification to 
       // the console. 
       if (result) 
       { 
        Console.WriteLine("The XML signature is valid."); 
       } 
       else 
       { 
        Console.WriteLine("The XML signature is not valid."); 
       } 

       Console.ReadLine(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e.Message); 
      } 
     } 

回答

0

在驗證確保u有

xmlDoc.PreserveWhitespace = false; 
3

在我看來,你是檢索錯誤的方式普布利克關鍵。首先檢查一個文件LicenceVerifier.PubKey.xml構建動作設置爲嵌入式資源

然後在調試運行這段代碼:

typeof(Program).Assembly.GetManifestResourceNames() 

,並確認正確的資源名稱傳遞給GetManifestResourceStream。我覺得你的代碼如下所示:

var asm = typeof(Program).Assembly; 
s = asm.GetManifestResourceStream(asm.GetName().Name + ".LicenceVerifier.PubKey.xml"); 

或者,如果一個公共密鑰位於子文件夾:

var subFolder = "NAME"; 
var asm = typeof(Program).Assembly; 
s = asm.GetManifestResourceStream(asm.GetName().Name + "." + subFolder + ".LicenceVerifier.PubKey.xml"); 

如果還是不行就意味着你的公鑰沒有按」不匹配一個私人的。爲了證實嘗試修改你的代碼是這樣的:

private static string SignXml(XmlDocument xmlDoc) 
{ 
    ... 
    return csp.ToXmlString(false); 
} 

public static Boolean VerifyXml(XmlDocument doc, string xmlKey) 
{ 
    RSACryptoServiceProvider csp = new RSACryptoServiceProvider(); 
    csp.FromXmlString(xmlKey); 
    ... 
} 

var xmlKey = SignXml(xml); 
var res = VerifyXml(xml, xmlKey); 

如果我的懷疑得到證實,那麼只需通過SignXml的修改版本返回XML代替LicenceVerifier.PubKey.xml的內容。

+0

兩者是相同的,仍然提供虛假 – AMH

+0

csp.ToXmlString(假); \t 「 4JDuhdDtaCPozDyndlaGp2CDVGPlPa + ziZHYQGyPF58L05SA8TKmsH977OOOCVaxozPCjmWU2q/aiSxP8Mv4L7QF600eRYqbN3G4RFkHGBUg7 + NbwOBX2 + SfOAv3FU6CdzoTeVoYZPHLz5NM7xQwVblLYItgH65gCpNIJfwNkZU = AQAB」 \t這等於pubkey.xml內容 – AMH

+0

你能示出了其中使用的是SignXml和VerifyXml碼? –