代码之家  ›  专栏  ›  技术社区  ›  S M Kamran

XML DSIG验证

  •  1
  • S M Kamran  · 技术社区  · 17 年前

            public static Boolean VerifyXml(XmlDocument document)
            {
                document.PreserveWhitespace = true;
                // Create a new CspParameters object to specify
                // a key container.
                CspParameters cspParams = new CspParameters();
                cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
    
                // Create a new RSA signing key and save it in the container. 
                //**Earlier was getting exception here in rsaKey object**
                RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
                // Create a new SignedXml object and pass it
                // the XML document class.
                SignedXml signedXml = new SignedXml(document);
    
                // Find the "Signature" node and create a new
                // XmlNodeList object.
                // It's guaranteed that there's always exists a signature 
                XmlNodeList nodeList = document.GetElementsByTagName("Signature");
    
                // Load the <signature> node.  
                signedXml.LoadXml((XmlElement)nodeList[0]);
    
                // Check the signature and return the result.
                bool isDone = signedXml.CheckSignature(rsaKey); //**This is returning false.**
                return isDone;
            }
    

    最初,当我的web应用程序尝试访问密钥容器时,我遇到了PermissionDenied异常。然而,我 暂时 将应用程序用户和IIS用户添加到管理员角色,并使用CasPol为我的web应用程序分配FullTrust安全策略。

    我的第二个问题是关于 signedXml.CheckSignature(rsaKey); 返回false。现在根据我的理解,由于XML文档是在另一台机器上进行数字签名的,因此用于签名的MAC存储在该机器上的KEY容器名称“XML_DSIG_RSA_KEY”,但当我试图在主机上验证签名时,会生成一个不同的MAC并将其存储在主机上的容器名称“XML _DSIG_RSA _KEY”中,因此数字签名没有得到验证。

    Q2:这个假设正确吗??以及应对这种情况的最佳方法是什么。..在这种情况下,我应该使用证书对XML文档进行数字签名,然后进行验证吗。我是否需要将证书与DSIG XML文档一起提供。???

    1 回复  |  直到 14 年前
        1
  •  4
  •   Rasmus Faber    17 年前

    首先回答您的第二个问题:您想用 public 用于签名的RSA密钥对的一部分。因此,您需要在验证机器上已经拥有(并信任)公钥,或者将包含公钥的证书与XML一起发送(它可以存储在XML签名结构中),然后验证证书是否由受信任的证书颁发机构颁发。

    要实现第一种情况,您可以调用 ToXmlString(false) 在发送端的密钥上,将结果存储在一个文件中,并将该文件保存在接收端。然后在接收端,读取文件并调用:

    RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
    rsaKey.ImportFromXml(publicKeyFromFile);
    

    第二种情况可以通过获取证书并将其添加到签名侧的签名中来完成,如下所示:

    KeyInfo keyInfo = new KeyInfo();
    X509Certificate cert = // load certificate
    keyInfo.AddClause(new KeyInfoX509Data(cert));
    signedXml.KeyInfo = keyInfo;
    

    如果证书是可信的,那么您只需调用以下命令即可在接收方验证签名:

    bool isDone = signedXml.CheckSignature();
    

    回答你的第一个问题:一旦你不再尝试访问私钥存储(你像以前一样调用RSACryptoServiceProvider构造函数),你应该能够在没有完全信任的情况下运行。