Domanda

Ho visto una serie di domande simili, ma nessuno che l'indirizzo esattamente quello che mi sto chiedendo.

Sto cercando di firmare un XML quindi verificare con la chiave pubblica utilizzando C#.

Mi segno il file XML con una chiave, quindi, esportare la chiave in un file XML.Poi prendete la chiave e l'XML firmato per un altro computer, importare la chiave utilizzando rsa.FromXmlString(doc.InnerXml), e verificare la firma XML.

Questo funziona se ho esportare le chiavi pubblica e privata per un XML utilizzando rsa.ToXmlString(True).Tuttavia, voglio esportare solo la mia chiave pubblica utilizzando rsa.ToXmlString(False).Se mi esporta solo la chiave pubblica e importalo nel secondo computer e tenta di convalidare la firma XML si dice che la firma non è valida.

Prima, dovrei essere in grado di verificare l'XML firmato con la sola chiave pubblica?

In secondo luogo, Se è vero, perché la mia verificare XML funzione funziona solo con il pub/priv chiave di coppia e non solo con la chiave pubblica?

Hai qualche saggezza su come eseguire il debug di questo problema?Io non sono sicuro di cosa fare, perché signedXml.CheckSignature(Key); non fornisce alcuna informazione sul perché non è riuscito.

La mia chiave di importazione, di esportazione chiave, segno XML, e verificare che funzioni XML sono al di sotto.Fatemi sapere se avete bisogno di ulteriori informazioni.

    public static void ImportKeyFromFile(string ContainerName, string inputFile)
    {
        try
        {
            // Create new XmlDocument.
            XmlDocument doc = new XmlDocument();

            // Load XML Document.
            doc.Load(inputFile);

            // Create the CspParameters object and set the key container 
            // name used to store the RSA key pair.
            CspParameters cp = new CspParameters();
            cp.KeyContainerName = ContainerName;

            // Create a new instance of RSACryptoServiceProvider that accesses
            // the key container MyKeyContainerName.
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);

            // Get RSA Parameters from xml document.
            rsa.FromXmlString(doc.InnerXml);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    public static void ExportKeyToFile(string ContainerName, string outputPath, bool private_key)
    {
        try
        {
            // Create the CspParameters object and set the key container 
            // name used to store the RSA key pair.
            CspParameters cp = new CspParameters();
            cp.KeyContainerName = ContainerName;

            // Create a new instance of RSACryptoServiceProvider that accesses
            // the key container MyKeyContainerName.
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);

            // Create new XmlDocument.
            XmlDocument doc = new XmlDocument();

            // Store rsa key.
            doc.InnerXml = rsa.ToXmlString(private_key);

            // Save Document.
            doc.Save(outputPath);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    public static Boolean VerifyXml(XmlDocument Doc, RSA Key)
    {
        // Check arguments. 
        if (Doc == null)
            throw new ArgumentException("Doc");
        if (Key == null)
            throw new ArgumentException("Key");

        // Create a new SignedXml object and pass it 
        // the XML document class.
        SignedXml signedXml = new SignedXml(Doc);

        // Find the "Signature" node and create a new 
        // XmlNodeList object.
        XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");

        // Throw an exception if no signature was found. 
        if (nodeList.Count <= 0)
        {
            throw new CryptographicException("Verification failed: No Signature was found in the document.");
        }

        // Load the first <signature> node.  
        signedXml.LoadXml((XmlElement)nodeList[0]);

        // Check the signature and return the result. 
        return signedXml.CheckSignature(Key);
    }
    public static void SignXml(XmlDocument xmlDoc, RSA Key)
    {
        // Check arguments. 
        if (xmlDoc == null)
            throw new ArgumentException("xmlDoc");
        if (Key == null)
            throw new ArgumentException("Key");

        // Create a SignedXml object.
        SignedXml signedXml = new SignedXml(xmlDoc);

        // Add the key to the SignedXml document.
        signedXml.SigningKey = Key;

        // Create a reference to be signed.
        Reference reference = new Reference();
        reference.Uri = "";

        // Add an enveloped transformation to the reference.
        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
        reference.AddTransform(env);

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

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

        // Get the XML representation of the signature and save 
        // it to an XmlElement object.
        XmlElement xmlDigitalSignature = signedXml.GetXml();

        // Append the element to the XML document.
        xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
    }
È stato utile?

Soluzione

Il problema è perché non è possibile memorizzare le chiavi pubbliche in un Contenitore di chiavi.Per verificare una firma con solo una chiave pubblica, è necessario importare la chiave dal file XML utilizzando rsa.FromXmlString poi passare rsa direttamente a Verificare la funzione di Firma.Se si tenta di memorizzare una chiave pubblica in un contenitore di chiavi e recuperarla in un secondo momento si finirà solo la creazione di una nuova chiave.Come memorizzare una chiave pubblica in una macchina a livello di contenitore di chiavi RSA

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top