SignedXml Kelas

Definisi

Menyediakan pembungkus pada objek tanda tangan XML inti untuk memfasilitasi pembuatan tanda tangan XML.

public ref class SignedXml
public class SignedXml
type SignedXml = class
Public Class SignedXml
Warisan
SignedXml

Contoh

Contoh kode berikut menunjukkan cara menandatangani dan memverifikasi seluruh dokumen XML menggunakan tanda tangan yang diselimuti.

//
// This example signs an XML file using an
// envelope signature. It then verifies the 
// signed XML.
//
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Xml;

public class SignVerifyEnvelope
{

    public static void Main(String[] args)
    {
        try
        {
           // Generate a signing key.
           RSA Key = RSA.Create();

           // Create an XML file to sign.
           CreateSomeXml("Example.xml");
           Console.WriteLine("New XML file created."); 

           // Sign the XML that was just created and save it in a 
           // new file.
           SignXmlFile("Example.xml", "signedExample.xml", Key);
           Console.WriteLine("XML file signed."); 

           // Verify the signature of the signed XML.
           Console.WriteLine("Verifying signature...");
           bool result = VerifyXmlFile("SignedExample.xml", Key);

           // 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.");
           }
        }
        catch(CryptographicException e)
        {
            Console.WriteLine(e.Message);
        }
    }

    // Sign an XML file and save the signature in a new file. This method does not  
    // save the public key within the XML file.  This file cannot be verified unless  
    // the verifying code has the key with which it was signed.
    public static void SignXmlFile(string FileName, string SignedFileName, RSA Key)
    {
        // Create a new XML document.
        XmlDocument doc = new XmlDocument();

        // Load the passed XML file using its name.
        doc.Load(new XmlTextReader(FileName));

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

        // 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.
        doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));
        
        if (doc.FirstChild is XmlDeclaration)  
        {
            doc.RemoveChild(doc.FirstChild);
        }

        // Save the signed XML document to a file specified
        // using the passed string.
        XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false));
        doc.WriteTo(xmltw);
        xmltw.Close();
    }

    // Verify the signature of an XML file against an asymmetric 
    // algorithm and return the result.
    public static Boolean VerifyXmlFile(String Name, RSA Key)
    {
        // Create a new XML document.
        XmlDocument xmlDocument = new XmlDocument();

        // Load the passed XML file into the document. 
        xmlDocument.Load(Name);

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

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

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

        // Check the signature and return the result.
        return signedXml.CheckSignature(Key);
    }

    // Create example data to sign.
    public static void CreateSomeXml(string FileName)
    {
        // Create a new XmlDocument object.
        XmlDocument document = new XmlDocument();

        // Create a new XmlNode object.
        XmlNode  node = document.CreateNode(XmlNodeType.Element, "", "MyElement", "samples");
        
        // Add some text to the node.
        node.InnerText = "Example text to be signed.";

        // Append the node to the document.
        document.AppendChild(node);

        // Save the XML document to the file name specified.
        XmlTextWriter xmltw = new XmlTextWriter(FileName, new UTF8Encoding(false));
        document.WriteTo(xmltw);
        xmltw.Close();
    }
}
'
' This example signs an XML file using an
' envelope signature. It then verifies the 
' signed XML.
'
Imports System.Security.Cryptography
Imports System.Security.Cryptography.X509Certificates
Imports System.Security.Cryptography.Xml
Imports System.Text
Imports System.Xml



Public Class SignVerifyEnvelope
   
   Overloads Public Shared Sub Main(args() As [String])
      Try
         ' Generate a signing key.
         Dim Key As RSA = RSA.Create()
         
         ' Create an XML file to sign.
         CreateSomeXml("Example.xml")
         Console.WriteLine("New XML file created.")
         
         ' Sign the XML that was just created and save it in a 
         ' new file.
         SignXmlFile("Example.xml", "signedExample.xml", Key)
         Console.WriteLine("XML file signed.")
         
         ' Verify the signature of the signed XML.
         Console.WriteLine("Verifying signature...")
         Dim result As Boolean = VerifyXmlFile("SignedExample.xml", Key)
         
         ' Display the results of the signature verification to 
         ' the console.
         If result Then
            Console.WriteLine("The XML signature is valid.")
         Else
            Console.WriteLine("The XML signature is not valid.")
         End If
      Catch e As CryptographicException
         Console.WriteLine(e.Message)
      End Try
   End Sub 
   
   
   
   ' Sign an XML file and save the signature in a new file. This method does not  
   ' save the public key within the XML file.  This file cannot be verified unless  
   ' the verifying code has the key with which it was signed.
   Public Shared Sub SignXmlFile(FileName As String, SignedFileName As String, Key As RSA)
      ' Create a new XML document.
      Dim doc As New XmlDocument()
      
      ' Load the passed XML file using its name.
      doc.Load(New XmlTextReader(FileName))
      
      ' Create a SignedXml object.
      Dim signedXml As New SignedXml(doc)
      
      ' Add the key to the SignedXml document. 
      signedXml.SigningKey = Key
      
      ' Create a reference to be signed.
      Dim reference As New Reference()
      reference.Uri = ""
      
      ' Add an enveloped transformation to the reference.
      Dim env As 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.
      Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
      
      ' Append the element to the XML document.
      doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
      
      If TypeOf doc.FirstChild Is XmlDeclaration Then
         doc.RemoveChild(doc.FirstChild)
      End If
      
      ' Save the signed XML document to a file specified
      ' using the passed string.
      Dim xmltw As New XmlTextWriter(SignedFileName, New UTF8Encoding(False))
      doc.WriteTo(xmltw)
      xmltw.Close()
   End Sub
   
   
   ' Verify the signature of an XML file against an asymmetric 
   ' algorithm and return the result.
   Public Shared Function VerifyXmlFile(Name As [String], Key As RSA) As [Boolean]
      ' Create a new XML document.
      Dim xmlDocument As New XmlDocument()
      
      ' Load the passed XML file into the document. 
      xmlDocument.Load(Name)
      
      ' Create a new SignedXml object and pass it
      ' the XML document class.
      Dim signedXml As New SignedXml(xmlDocument)
      
      ' Find the "Signature" node and create a new
      ' XmlNodeList object.
      Dim nodeList As XmlNodeList = xmlDocument.GetElementsByTagName("Signature")
      
      ' Load the signature node.
      signedXml.LoadXml(CType(nodeList(0), XmlElement))
      
      ' Check the signature and return the result.
      Return signedXml.CheckSignature(Key)
   End Function 
   
   
   
   ' Create example data to sign.
   Public Shared Sub CreateSomeXml(FileName As String)
      ' Create a new XmlDocument object.
      Dim document As New XmlDocument()
      
      ' Create a new XmlNode object.
      Dim node As XmlNode = document.CreateNode(XmlNodeType.Element, "", "MyElement", "samples")
      
      ' Add some text to the node.
      node.InnerText = "Example text to be signed."
      
      ' Append the node to the document.
      document.AppendChild(node)
      
      ' Save the XML document to the file name specified.
      Dim xmltw As New XmlTextWriter(FileName, New UTF8Encoding(False))
      document.WriteTo(xmltw)
      xmltw.Close()
   End Sub 
End Class

Contoh kode berikut menunjukkan cara menandatangani dan memverifikasi satu elemen dokumen XML menggunakan tanda tangan menyelimuti.

//
// This example signs an XML file using an
// envelope signature. It then verifies the
// signed XML.
//
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Xml;

public class SignVerifyEnvelope
{

    public static void Main(String[] args)
    {
        // Generate a signing key.
       RSA Key = RSA.Create();

       try
       {
           // Specify an element to sign.
           string[] elements =  { "#tag1" };

           // Sign an XML file and save the signature to a
           // new file.
           SignXmlFile("Test.xml", "SignedExample.xml", Key, elements);
           Console.WriteLine("XML file signed.");

           // Verify the signature of the signed XML.
           Console.WriteLine("Verifying signature...");

           bool result = VerifyXmlFile("SignedExample.xml");

           // 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.");
           }
       }
       catch (CryptographicException e)
       {
           Console.WriteLine(e.Message);
       }
       finally
       {
           // Clear resources associated with the
           // RSA instance.
           Key.Clear();
       }
   }

    // Sign an XML file and save the signature in a new file.
    public static void SignXmlFile(string FileName, string SignedFileName, RSA Key, string[] ElementsToSign)
    {
        // Check the arguments.
        if (FileName == null)
            throw new ArgumentNullException("FileName");
        if (SignedFileName == null)
            throw new ArgumentNullException("SignedFileName");
        if (Key == null)
            throw new ArgumentNullException("Key");
        if (ElementsToSign == null)
            throw new ArgumentNullException("ElementsToSign");

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

        // Format the document to ignore white spaces.
        doc.PreserveWhitespace = false;

        // Load the passed XML file using it's name.
        doc.Load(new XmlTextReader(FileName));

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

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

        // Loop through each passed element to sign
        // and create a reference.
        foreach (string s in ElementsToSign)
        {
            // Create a reference to be signed.
            Reference reference = new Reference();
            reference.Uri = s;

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

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

        // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
        KeyInfo keyInfo = new KeyInfo();
        keyInfo.AddClause(new RSAKeyValue((RSA)Key));
        signedXml.KeyInfo = keyInfo;

        // 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.
        doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));

        if (doc.FirstChild is XmlDeclaration)
        {
            doc.RemoveChild(doc.FirstChild);
        }

        // Save the signed XML document to a file specified
        // using the passed string.
        XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false));
        doc.WriteTo(xmltw);
        xmltw.Close();
    }
    // Verify the signature of an XML file and return the result.
    public static Boolean VerifyXmlFile(String Name)
    {
        // Check the arguments.
        if (Name == null)
            throw new ArgumentNullException("Name");

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

        // Format using white spaces.
        xmlDocument.PreserveWhitespace = true;

        // Load the passed XML file into the document.
        xmlDocument.Load(Name);

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

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

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

        // Check the signature and return the result.
        return signedXml.CheckSignature();
    }
}
' This example signs an XML file using an
' envelope signature. It then verifies the 
' signed XML.
'
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Text
Imports System.Xml



Module SignVerifyEnvelope



    Sub Main(ByVal args() As String)
        ' Generate a signing key.
        Dim Key As RSA = RSA.Create()

        Try
            ' Specify an element to sign. 
            Dim elements As String() = New String() {"#tag1"}

            ' Sign an XML file and save the signature to a 
            ' new file.
            SignXmlFile("Test.xml", "SignedExample.xml", Key, elements)
            Console.WriteLine("XML file signed.")

            ' Verify the signature of the signed XML.
            Console.WriteLine("Verifying signature...")

            Dim result As Boolean = VerifyXmlFile("SignedExample.xml")

            ' Display the results of the signature verification to \
            ' the console.
            If result Then
                Console.WriteLine("The XML signature is valid.")
            Else
                Console.WriteLine("The XML signature is not valid.")
            End If
        Catch e As CryptographicException
            Console.WriteLine(e.Message)
        Finally
            ' Clear resources associated with the 
            ' RSA instance.
            Key.Clear()
        End Try

    End Sub


    ' Sign an XML file and save the signature in a new file.
    Sub SignXmlFile(ByVal FileName As String, ByVal SignedFileName As String, ByVal Key As RSA, ByVal ElementsToSign() As String)
        ' Check the arguments.  
        If FileName Is Nothing Then
            Throw New ArgumentNullException("FileName")
        End If
        If SignedFileName Is Nothing Then
            Throw New ArgumentNullException("SignedFileName")
        End If
        If Key Is Nothing Then
            Throw New ArgumentNullException("Key")
        End If
        If ElementsToSign Is Nothing Then
            Throw New ArgumentNullException("ElementsToSign")
        End If
        ' Create a new XML document.
        Dim doc As New XmlDocument()

        ' Format the document to ignore white spaces.
        doc.PreserveWhitespace = False

        ' Load the passed XML file using it's name.
        doc.Load(New XmlTextReader(FileName))

        ' Create a SignedXml object.
        Dim signedXml As New SignedXml(doc)

        ' Add the key to the SignedXml document. 
        signedXml.SigningKey = Key

        ' Loop through each passed element to sign 
        ' and create a reference.
        Dim s As String
        For Each s In ElementsToSign
            ' Create a reference to be signed.
            Dim reference As New Reference()
            reference.Uri = s

            ' Add an enveloped transformation to the reference.
            Dim env As New XmlDsigEnvelopedSignatureTransform()
            reference.AddTransform(env)

            ' Add the reference to the SignedXml object.
            signedXml.AddReference(reference)
        Next s

        ' Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
        Dim keyInfo As New KeyInfo()
        keyInfo.AddClause(New RSAKeyValue(CType(Key, RSA)))
        signedXml.KeyInfo = keyInfo

        ' Compute the signature.
        signedXml.ComputeSignature()

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

        ' Append the element to the XML document.
        doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))


        If TypeOf doc.FirstChild Is XmlDeclaration Then
            doc.RemoveChild(doc.FirstChild)
        End If

        ' Save the signed XML document to a file specified
        ' using the passed string.
        Dim xmltw As New XmlTextWriter(SignedFileName, New UTF8Encoding(False))
        doc.WriteTo(xmltw)
        xmltw.Close()

    End Sub

    ' Verify the signature of an XML file and return the result.
    Function VerifyXmlFile(ByVal Name As String) As [Boolean]
        ' Check the arguments.  
        If Name Is Nothing Then
            Throw New ArgumentNullException("Name")
        End If
        ' Create a new XML document.
        Dim xmlDocument As New XmlDocument()

        ' Format using white spaces.
        xmlDocument.PreserveWhitespace = True

        ' Load the passed XML file into the document. 
        xmlDocument.Load(Name)

        ' Create a new SignedXml object and pass it
        ' the XML document class.
        Dim signedXml As New SignedXml(xmlDocument)

        ' Find the "Signature" node and create a new
        ' XmlNodeList object.
        Dim nodeList As XmlNodeList = xmlDocument.GetElementsByTagName("Signature")

        ' Load the signature node.
        signedXml.LoadXml(CType(nodeList(0), XmlElement))

        ' Check the signature and return the result.
        Return signedXml.CheckSignature()

    End Function
End Module

Keterangan

Kelas SignedXml ini adalah implementasi .NET dari Sintaks dan Spesifikasi Pemrosesan Tanda Tangan XML World Wide Web Consortium (W3C), juga dikenal sebagai XMLDSIG (XML Digital Signature). XMLDSIG adalah cara berbasis standar dan dapat dioperasikan untuk menandatangani dan memverifikasi semua atau sebagian dokumen XML atau data lain yang dapat diatasi dari Pengidentifikasi Sumber Daya Seragam (URI).

SignedXml Gunakan kelas setiap kali Anda perlu berbagi data XML yang ditandatangani antara aplikasi atau organisasi dengan cara standar. Setiap data yang ditandatangani menggunakan kelas ini dapat diverifikasi oleh implementasi spesifikasi W3C yang sesuai untuk XMLDSIG.

Kelas ini SignedXml memungkinkan Anda membuat tiga jenis tanda tangan digital XML berikut:

Tipe Tanda Tangan Deskripsi
Tanda tangan yang diselimuti Tanda tangan terkandung dalam elemen XML yang sedang ditandatangani.
Tanda Tangan Pembungkus XML yang ditandatangani terkandung dalam <Signature> elemen .
Tanda tangan terpisah internal Tanda tangan dan XML yang ditandatangani berada dalam dokumen yang sama, tetapi tidak ada elemen yang berisi yang lain.

Ada juga jenis tanda tangan keempat yang disebut tanda tangan eksternal yang terlepas, yaitu ketika data dan tanda tangan berada dalam dokumen XML terpisah. Kelas SignedXml tidak mendukung tanda tangan terpisah eksternal.

Struktur tanda tangan XML

XMLDSIG membuat <Signature> elemen, yang berisi tanda tangan digital dokumen XML atau data lain yang dapat diatasi dari URI. Elemen ini <Signature> dapat secara opsional berisi informasi tentang tempat menemukan kunci yang akan memverifikasi tanda tangan dan algoritma kriptografi mana yang digunakan untuk penandatanganan. Struktur dasarnya adalah sebagai berikut:

<Signature xmlns:ds="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>Base64EncodedValue==</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>AnotherBase64EncodedValue===</SignatureValue>
</Signature>

Bagian utama dari struktur ini adalah:

  • Elemen <CanonicalizationMethod>

    Menentukan aturan untuk menulis ulang elemen Signature dari XML/teks ke dalam byte untuk validasi tanda tangan. Nilai default dalam .NET adalah http://www.w3.org/TR/2001/REC-xml-c14n-20010315, yang mengidentifikasi algoritma tepercaya. Elemen ini diwakili oleh SignedInfo.CanonicalizationMethod properti .

  • Elemen <SignatureMethod>

    Menentukan algoritma yang digunakan untuk pembuatan dan validasi tanda tangan, yang diterapkan ke <Signature> elemen untuk menghasilkan nilai dalam <SignatureValue>. Dalam contoh sebelumnya, nilai http://www.w3.org/2000/09/xmldsig#rsa-sha1 mengidentifikasi tanda tangan RSA PKCS1 SHA-1. Karena masalah tabrakan dengan SHA-1, Microsoft merekomendasikan model keamanan berdasarkan SHA-256 atau lebih baik. Elemen ini diwakili oleh SignatureMethod properti .

  • Elemen <SignatureValue>

    Menentukan tanda tangan kriptografi untuk <Signature> elemen . Jika tanda tangan ini tidak memverifikasi, maka beberapa bagian <Signature> blok dirusak, dan dokumen dianggap tidak valid. Selama <CanonicalizationMethod> nilainya dapat dipercaya, nilai ini sangat tahan terhadap perubahan. Elemen ini diwakili oleh SignatureValue properti .

  • Elemen URI dengan atribut <Reference>

    Menentukan objek data menggunakan referensi URI. Atribut ini diwakili oleh Reference.Uri properti .

    • Tidak menentukan URI atribut, yaitu, mengatur Reference.Uri properti ke null, berarti bahwa aplikasi penerima diharapkan mengetahui identitas objek. Dalam kebanyakan kasus, null URI akan menimbulkan pengecualian. Jangan gunakan null URI, kecuali aplikasi Anda beroperasi dengan protokol yang memerlukannya.

    • Mengatur atribut URI ke string kosong menunjukkan bahwa elemen akar dokumen sedang ditandatangani, sebuah bentuk tanda tangan terbungkus.

    • Jika nilai atribut URI dimulai dengan #, nilai harus sesuai dengan elemen dalam dokumen saat ini. Formulir ini dapat digunakan dengan salah satu dari jenis tanda tangan yang didukung (tanda tangan yang diselimuti, tanda tangan menyelimuti, atau tanda tangan terpisah internal).

    • Hal lain dianggap sebagai tanda tangan terpisah sumber daya eksternal dan tidak didukung oleh kelas SignedXml.

  • Elemen <Transforms>

    Berisi daftar <Transform> elemen yang diurutkan yang menjelaskan bagaimana penanda tangan memperoleh objek data yang dicerna. Algoritma transformasi mirip dengan metode kanonisisasi, tetapi alih-alih menulis <Signature> ulang elemen, ia menulis ulang konten yang diidentifikasi oleh URI atribut <Reference> elemen . Elemen <Transforms> diwakili oleh TransformChain kelas .

    • Setiap algoritma transformasi didefinisikan sebagai menerima XML (kumpulan simpul XPath) atau byte sebagai input. Jika format data saat ini berbeda dari persyaratan input transformasi, aturan konversi diterapkan.

    • Setiap algoritma transformasi didefinisikan untuk menghasilkan XML atau byte sebagai output.

    • Jika output algoritma transformasi terakhir tidak didefinisikan dalam byte (atau tidak ada transformasi yang ditentukan), maka metode kanonisisasi digunakan sebagai transformasi implisit (bahkan jika algoritma yang berbeda ditentukan dalam <CanonicalizationMethod> elemen ).

    • Nilai http://www.w3.org/2000/09/xmldsig#enveloped-signature untuk algoritma transformasi mengodekan aturan yang ditafsirkan sebagai hapus <Signature> elemen dari dokumen. Jika tidak, pemverifikasi tanda tangan terbungkus akan memproses dokumen, termasuk tanda tangan, tetapi penanda tangan akan memproses dokumen sebelum tanda tangan diterapkan, mengakibatkan hasil yang berbeda.

  • Elemen <DigestMethod>

    Mengidentifikasi metode hash (hash kriptografi) untuk diterapkan pada konten yang telah diubah yang diidentifikasi oleh atribut URI dari elemen <Reference>. Ini diwakili oleh Reference.DigestMethod properti .

Memilih metode kanonisisasi

Kecuali mengoperasikan dengan spesifikasi yang memerlukan penggunaan nilai yang berbeda, kami sarankan Anda menggunakan metode kanonisisasi .NET default, yang merupakan algoritma XML-C14N 1.0, yang nilainya adalah http://www.w3.org/TR/2001/REC-xml-c14n-20010315. Algoritma XML-C14N 1.0 diperlukan untuk didukung oleh semua implementasi XMLDSIG, terutama karena merupakan transformasi akhir implisit untuk diterapkan.

Ada versi algoritma kanonisisasi yang mendukung mempertahankan komentar. Metode kanonisisasi yang mempertahankan komentar tidak disarankan karena melanggar prinsip "tanda apa yang terlihat". Artinya, komentar dalam <Signature> elemen tidak akan mengubah logika pemrosesan tentang bagaimana tanda tangan dilakukan, hanya apa nilai tanda tangannya. Ketika dikombinasikan dengan algoritma tanda tangan yang lemah, mengizinkan komentar disertakan memberikan kebebasan yang tidak perlu kepada penyerang untuk memaksa terjadinya tabrakan hash, sehingga membuat dokumen yang telah diubah tampak sah. Di .NET Framework, hanya kanonisator bawaan yang didukung secara default. Untuk mendukung kanonisator tambahan atau kustom, lihat properti SafeCanonicalizationMethods. Jika dokumen menggunakan metode kanonisisasi yang tidak ada dalam koleksi yang diwakili oleh SafeCanonicalizationMethods properti , maka CheckSignature metode akan mengembalikan false.

Note

Aplikasi dengan sifat sangat defensif dapat menghapus nilai apa pun yang tidak diharapkan digunakan penanda tangan dari koleksi data SafeCanonicalizationMethods.

Apakah nilai referensi aman dari perubahan?

Ya, <Reference> nilai aman dari gangguan. .NET memverifikasi komputasi <SignatureValue> sebelum memproses salah <Reference> satu nilai dan transformasi terkaitnya, dan akan membatalkan lebih awal untuk menghindari instruksi pemrosesan yang berpotensi berbahaya.

Pilih elemen yang akan ditandatangani

Kami menyarankan agar Anda menggunakan nilai "" untuk URI atribut (atau mengatur Uri properti ke string kosong), jika memungkinkan. Ini berarti seluruh dokumen dipertimbangkan untuk perhitungan ringkasan, yang berarti seluruh dokumen dilindungi dari manipulasi.

Sangat umum untuk melihat URI nilai dalam bentuk jangkar seperti #foo, mengacu pada elemen yang atribut ID-nya adalah "foo". Sayangnya, mudah untuk ini dirusak karena ini hanya mencakup konten elemen target, bukan konteksnya. Menyalahgunakan perbedaan ini dikenal sebagai Pembungkus Tanda Tangan XML (XSW).

Jika aplikasi Anda menganggap komentar semantik (yang tidak umum saat berhadapan dengan XML), maka Anda harus menggunakan "#xpointer(/)" alih-alih "", dan "#xpointer(id('foo'))" alih-alih "#foo". Versi #xpointer ditafsirkan sebagai termasuk komentar, sementara formulir nama pendek tidak termasuk komentar.

Jika Anda perlu menerima dokumen yang hanya dilindungi sebagian dan Anda ingin memastikan bahwa Anda membaca konten yang sama seperti yang dilindungi oleh tanda tangan, gunakan metode GetIdElement.

Pertimbangan keamanan tentang elemen KeyInfo

Data dalam elemen opsional <KeyInfo> (yaitu, KeyInfo properti ), yang berisi kunci untuk memvalidasi tanda tangan, tidak boleh dipercaya.

Secara khusus, ketika nilai KeyInfo mewakili kunci publik RSA, DSA, atau ECDSA tanpa embel-embel, dokumen mungkin telah dimanipulasi, meskipun metode CheckSignature melaporkan bahwa tanda tangan tersebut valid. Ini dapat terjadi karena entitas yang melakukan perusakan hanya perlu menghasilkan kunci baru dan menandatangani kembali dokumen yang dirusak dengan kunci baru tersebut. Jadi, kecuali aplikasi Anda memverifikasi bahwa kunci publik adalah nilai yang diharapkan, dokumen harus diperlakukan seolah-olah itu dirusak. Ini mengharuskan aplikasi Anda memeriksa kunci publik yang disematkan dalam dokumen dan memverifikasinya terhadap daftar nilai yang diketahui untuk konteks dokumen. Misalnya, jika dokumen bisa dimengerti telah dikeluarkan oleh pengguna yang dikenal, Anda akan memeriksa kunci terhadap daftar kunci yang sudah dikenal yang digunakan oleh pengguna tersebut.

Anda juga dapat memverifikasi kunci setelah memproses dokumen dengan menggunakan CheckSignatureReturningKey metode , alih-alih menggunakan CheckSignature metode . Tetapi, untuk keamanan optimal, Anda harus memverifikasi kunci sebelumnya.

Sebagai alternatif, pertimbangkan untuk mencoba kunci publik terdaftar pengguna, daripada membaca elemen <KeyInfo>.

Pertimbangan keamanan tentang elemen X509Data

Elemen opsional <X509Data> adalah turunan dari <KeyInfo> elemen dan berisi satu atau beberapa sertifikat atau pengidentifikasi X509 untuk sertifikat X509. Data dalam <X509Data> elemen juga tidak boleh dipercaya secara inheren.

Saat memverifikasi dokumen dengan elemen yang disematkan <X509Data> , .NET hanya memverifikasi bahwa data diselesaikan ke sertifikat X509 yang kunci publiknya dapat berhasil digunakan untuk memvalidasi tanda tangan dokumen. Tidak seperti memanggil CheckSignature metode dengan parameter yang verifySignatureOnly diatur ke false, tidak ada pemeriksaan pencabutan yang dilakukan, tidak ada rantai kepercayaan yang diperiksa, dan tidak ada masa kedaluwarsa yang diverifikasi. Bahkan jika aplikasi Anda mengekstrak sertifikat itu sendiri dan meneruskannya ke CheckSignature metode dengan parameter verifySignatureOnly yang disetel ke false, itu masih belum merupakan validasi yang cukup untuk mencegah perusakan dokumen. Sertifikat masih perlu diverifikasi sebagai sesuai untuk dokumen yang ditandatangani.

Menggunakan sertifikat penandatanganan yang disematkan dapat memberikan strategi rotasi kunci yang berguna, baik dalam <X509Data> bagian atau dalam konten dokumen. Saat menggunakan pendekatan ini, aplikasi harus mengekstrak sertifikat secara manual dan melakukan validasi yang mirip dengan:

  • Sertifikat dikeluarkan secara langsung atau melalui rantai oleh Otoritas Sertifikat (CA) yang sertifikat publiknya disematkan dalam aplikasi.

    Menggunakan daftar kepercayaan yang disediakan OS tanpa pemeriksaan tambahan, seperti nama subjek yang diketahui, tidak cukup untuk mencegah perubahan di SignedXml.

  • Sertifikat terverifikasi belum kedaluwarsa saat penandatanganan dokumen (atau "sekarang" untuk pemrosesan dokumen mendekati waktu nyata).

  • Untuk sertifikat berumur panjang yang dikeluarkan oleh CA yang memiliki fitur pencabutan, verifikasi bahwa sertifikat tidak dicabut.

  • Subjek sertifikat diverifikasi sebagai sesuai dengan dokumen saat ini.

Memilih algoritma transformasi

Jika Anda mengoperasikan dengan spesifikasi yang telah menentukan nilai tertentu (seperti XrML), maka Anda perlu mengikuti spesifikasinya. Jika Anda memiliki tanda tangan yang diselimuti (seperti saat menandatangani seluruh dokumen), maka Anda perlu menggunakan http://www.w3.org/2000/09/xmldsig#enveloped-signature (diwakili oleh XmlDsigEnvelopedSignatureTransform kelas ). Anda juga dapat menentukan transformasi XML-C14N implisit, tetapi tidak perlu. Untuk tanda tangan digital yang menyelimuti atau terpisah, transformasi tidak diperlukan. Transformasi implisit XML-C14N menangani segalanya.

Dengan pembaruan keamanan yang diperkenalkan oleh buletin Microsoft Security MS16-035, .NET membatasi transformasi apa yang dapat digunakan dalam verifikasi dokumen secara default. Transformasi yang tidak tepercaya menyebabkan CheckSignature selalu mengembalikan false. Secara khusus, transformasi yang memerlukan input tambahan (ditentukan sebagai elemen turunan dalam XML) tidak diizinkan karena kerentanan penyalahgunaan mereka oleh pengguna berbahaya. W3C menyarankan untuk menghindari transformasi XPath dan XSLT, yang merupakan dua transformasi utama yang terpengaruh oleh pembatasan ini.

Masalah dengan referensi eksternal

Jika aplikasi tidak memverifikasi bahwa referensi eksternal tampaknya sesuai untuk konteks saat ini, mereka dapat disalahgunakan dengan cara yang menyediakan banyak kerentanan keamanan (termasuk Penolakan Layanan, Penolakan Refleksi Terdistribusi Layanan, Pengungkapan Informasi, Bypass Tanda Tangan, dan Eksekusi Kode Jarak Jauh). Bahkan jika aplikasi memvalidasi URI referensi eksternal, akan tetap ada masalah sumber daya yang dimuat dua kali: sekali ketika aplikasi Anda membacanya, dan sekali ketika SignedXml membacanya. Karena tidak ada jaminan bahwa langkah-langkah baca dan verifikasi dokumen aplikasi memiliki konten yang sama, tanda tangan tidak memberikan kepercayaan.

Mengingat risiko referensi eksternal, SignedXml melemparkan pengecualian ketika referensi eksternal ditemui. Untuk informasi selengkapnya tentang masalah ini, lihat aplikasi .NET mengalami kesalahan pengecualian.

Konstruktor

Nama Deskripsi
SignedXml()

Menginisialisasi instans baru dari kelas SignedXml.

SignedXml(XmlDocument)

Menginisialisasi instans SignedXml baru kelas dari dokumen XML yang ditentukan.

SignedXml(XmlElement)

Menginisialisasi instans SignedXml baru kelas dari objek yang ditentukan XmlElement .

Bidang

Nama Deskripsi
m_signature

Signature Mewakili objek objek saat iniSignedXml.

m_strSigningKeyName

Mewakili nama kunci yang diinstal yang akan digunakan untuk menandatangani SignedXml objek.

XmlDecryptionTransformUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk transformasi dekripsi mode XML. Bidang ini konstan.

XmlDsigBase64TransformUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk transformasi dasar 64. Bidang ini konstan.

XmlDsigC14NTransformUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk transformasi XML Kanonis. Bidang ini konstan.

XmlDsigC14NWithCommentsTransformUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk transformasi XML Kanonis, dengan komentar. Bidang ini konstan.

XmlDsigCanonicalizationUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk algoritma kanonisisasi standar untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigCanonicalizationWithCommentsUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk algoritma kanonisisasi standar untuk tanda tangan digital XML dan menyertakan komentar. Bidang ini konstan.

XmlDsigDSAUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk algoritma standar DSA untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigEnvelopedSignatureTransformUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk transformasi tanda tangan yang diselimuti. Bidang ini konstan.

XmlDsigExcC14NTransformUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk kanonisisasi XML eksklusif. Bidang ini konstan.

XmlDsigExcC14NWithCommentsTransformUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk kanonisisasi XML eksklusif, dengan komentar. Bidang ini konstan.

XmlDsigHMACSHA1Url

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk algoritma standar HMACSHA1 untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigMinimalCanonicalizationUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk algoritma kanonisisasi minimal standar untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigNamespaceUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk namespace standar untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigRSASHA1Url

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk metode tanda tangan standar RSA untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigRSASHA256Url

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk RSA variasi metode tanda tangan SHA-256 untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigRSASHA384Url

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk RSA variasi metode tanda tangan SHA-384 untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigRSASHA512Url

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk RSA variasi metode tanda tangan SHA-512 untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigSHA1Url

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk metode hash standar SHA1 untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigSHA256Url

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk metode hash standar SHA256 untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigSHA384Url

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk metode hash standar SHA384 untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigSHA512Url

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk metode hash standar SHA512 untuk tanda tangan digital XML. Bidang ini konstan.

XmlDsigXPathTransformUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk Bahasa Jalur XML (XPath). Bidang ini konstan.

XmlDsigXsltTransformUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk transformasi XSLT. Bidang ini konstan.

XmlLicenseTransformUrl

Mewakili Pengidentifikasi Sumber Daya Seragam (URI) untuk algoritma transformasi lisensi yang digunakan untuk menormalkan lisensi XrML untuk tanda tangan.

Properti

Nama Deskripsi
EncryptedXml

Mendapatkan atau mengatur EncryptedXml objek yang menentukan aturan pemrosesan enkripsi XML.

KeyInfo

Mendapatkan atau mengatur KeyInfo objek objek saat ini SignedXml .

Resolver

Mengatur objek saat ini XmlResolver .

SafeCanonicalizationMethods

Mendapatkan nama metode yang algoritma kanonisisasinya diizinkan secara eksplisit.

Signature

Signature Mendapatkan objek objek saat iniSignedXml.

SignatureFormatValidator

Mendapatkan delegasi yang akan dipanggil untuk memvalidasi format (bukan keamanan kriptografi) tanda tangan XML.

SignatureLength

Mendapatkan panjang tanda tangan untuk objek saat ini SignedXml .

SignatureMethod

Mendapatkan metode tanda tangan objek saat ini SignedXml .

SignatureValue

Mendapatkan nilai tanda tangan objek saat ini SignedXml .

SignedInfo

SignedInfo Mendapatkan objek objek saat iniSignedXml.

SigningKey

Mendapatkan atau mengatur kunci algoritma asimetris yang SignedXml digunakan untuk menandatangani objek.

SigningKeyName

Mendapatkan atau mengatur nama kunci terinstal yang akan digunakan untuk menandatangani SignedXml objek.

Metode

Nama Deskripsi
AddObject(DataObject)

DataObject Menambahkan objek ke daftar objek yang akan ditandatangani.

AddReference(Reference)

Reference Menambahkan objek ke SignedXml objek yang menjelaskan metode hash, nilai hash, dan transformasi untuk digunakan untuk membuat tanda tangan digital XML.

CheckSignature()

Menentukan apakah Signature properti memverifikasi menggunakan kunci publik dalam tanda tangan.

CheckSignature(AsymmetricAlgorithm)

Menentukan apakah Signature properti memverifikasi untuk kunci yang ditentukan.

CheckSignature(KeyedHashAlgorithm)

Menentukan apakah Signature properti memverifikasi untuk algoritma kode autentikasi pesan (MAC) yang ditentukan.

CheckSignature(X509Certificate2, Boolean)

Menentukan apakah Signature properti memverifikasi untuk objek yang ditentukan X509Certificate2 dan, secara opsional, apakah sertifikat valid.

CheckSignatureReturningKey(AsymmetricAlgorithm)

Menentukan apakah Signature properti memverifikasi menggunakan kunci publik dalam tanda tangan.

ComputeSignature()

Menghitung tanda tangan digital XML.

ComputeSignature(KeyedHashAlgorithm)

Menghitung tanda tangan digital XML menggunakan algoritma kode autentikasi pesan (MAC) yang ditentukan.

Equals(Object)

Menentukan apakah objek yang ditentukan sama dengan objek saat ini.

(Diperoleh dari Object)
GetHashCode()

Berfungsi sebagai fungsi hash default.

(Diperoleh dari Object)
GetIdElement(XmlDocument, String)

Mengembalikan XmlElement objek dengan ID yang ditentukan dari objek yang ditentukan XmlDocument .

GetPublicKey()

Mengembalikan kunci publik tanda tangan.

GetType()

Mendapatkan Type instans saat ini.

(Diperoleh dari Object)
GetXml()

Mengembalikan representasi XML objek SignedXml .

LoadXml(XmlElement)

Memuat status SignedXml dari elemen XML.

MemberwiseClone()

Membuat salinan dangkal dari Objectsaat ini.

(Diperoleh dari Object)
ToString()

Mengembalikan string yang mewakili objek saat ini.

(Diperoleh dari Object)

Berlaku untuk

Lihat juga