Specifiche di base : XML Digital Signature in pillole…


Per chi di voi ha partecipato al Panel della sicurezza che ho tenuto a WPC 2007 (o letto le slides) può capire il perchè sto scrivendo questa serie di post... "in pillole". Infatti per comprendere completamente alcuni nuovi attacchi sul fronte XML/Web Services è necessario approfondire il funzionamento di alcune specifiche di sicurezza nel mondo XML, perciò... eccoci qua 🙂

XML Digital Signature [XMLDSIG  xmlns="http://www.w3.org/2000/09/xmldsig#"] è il risultato di un lavoro congiunto tra il W3C e IETF. Lo scopo di questa specifica è di definire una sintassi XML e un insieme di regole per la creazione, la rappresentazione e la verifica di una o più firme digitali generate da documenti binari o XML. Al contrario XMLDSIG non si occupa del problema della generazione delle chiavi crittografiche, dell’associazione di tali chiavi ad utenti, servizi o processi e dei lagami di trust che devono essere impostati tra chi firma e chi verifica. Questa scelta permette di evidenziare la differenza tra le operazioni crittografiche e le policy di validazione che possono cambiare a seconda dello scenario applicativo.
La specifica prevede tre modalità per applicare le firme digitali in un formato XML:

  • Enveloped
  • Enveloping
  • Detached.

image

Come si può notare ciò che distingue una modalità dall’altra è il posizionamento dell’elemento <Signature> rispetto al documento firmato. Nel caso di Enveloped il contenuto da firmare contiene l'elemento <Signature> mentre si ha la situazione inversa nel formato Enveloping. La modalità Detached indica che il documento da firmare è completamente disgiunto dal documento contenente la firma digitale. [XMLDSIG] XML Digital Signature può firmare contemporaneamente più entità rendendo possibile associare in un unico documento XML le diverse modalità di firma.

Nella figura sottostante è rappresentato un esempio di documento XML firmato secondo la specifica [XMLDSIG] nel formato Enveloping.

image

La struttura di un file XML firmato secondo la specifica è il seguente :

<Signature ID?>
     <SignedInfo>
         <CanonicalizationMethod/>
         <SignatureMethod/>
         (<Reference URI? >
             (<Transforms>)?
            <DigestMethod>
            <DigestValue>
         </Reference>)+
     </SignedInfo>
     <SignatureValue>
     (<KeyInfo>)?
     (<Object ID?>)*
</Signature>

Come si può notare il file XML firmato contiene un elemento Signature al cui interno troviamo tre aree principali:

  • SignedInfo
  • SignatureValue
  • KeyInfo

SignedInfo, il cui schema è :

<element name="SignedInfo" type="ds:SignedInfoType"/>
   <complexType name="SignedInfoType">
     <sequence>
       <element ref="ds:CanonicalizationMethod"/>
       <element ref="ds:SignatureMethod"/>
       <element ref="ds:Reference" maxOccurs="unbounded"/>
     </sequence>
     <attribute name="Id" type="ID" use="optional"/>
   </complexType>

rappresenta sempre il primo elemento di ds:Signature e racchiude il contenuto da firmare e tutte le informazioni necessarie per rappresentare e gestire tali informazioni.
Infatti il primo sottoelemento obbligatorio, CanonicalizationMethod, indica quale algoritmo di normalizzazione deve essere applicato a tutto SignedInfo mentre SignatureMethod,anch’esso obbligatorio, rappresenta l’algoritmo di firma da utilizzare alla forma normalizzata di SignedInfo. L’elemento Reference (maxOccurs="unbounded" significa che possono essere presenti un numero arbitrario di elementi di questo tipo) raccoglie l’informazione da firmare. Lo schema di Reference

<element name="Reference" type="ds:ReferenceType"/>
   <complexType name="ReferenceType">
     <sequence>
       <element ref="ds:Transforms" minOccurs="0"/>
       <element ref="ds:DigestMethod"/>
       <element ref="ds:DigestValue"/>
     </sequence>
     <attribute name="Id" type="ID" use="optional"/>
     <attribute name="URI" type="anyURI" use="optional"/>
     <attribute name="Type" type="anyURI" use="optional"/>
   </complexType>

ci mostra chiaramente che :

il contenuto da firmare non è il documento stesso ma bensi l’hash del documento (DigestMethod e DigestValue) più le informazioni di rappresentazione.

Quindi la specifica prevede che per ogni documento da firmare vi sia un corrispondente elemento Reference all’interno di ds:SignedInfo il quale contiene l’informazione dell’algoritmo di hashing da applicare al documento in chiaro e il rispettivo valore di hash convertito in Base64. L’elemento opzionale Transform permette di specificare una sequenza di trasformazioni (dalle più semplici come Base64, Canonicalization a soluzioni più complesse basate su XPath o XSLT) da applicare al documento prima di essere firmato garantendo la massima flessibilità nella gestione dei dati.

Figura6

Queste informazioni verranno utilizzate durante la fase di firma e di verifica. Nell’esempio precedente possiamo vedere che l’elemento SignedInfo contiene il riferimento all’algoritmo di canonicalizzazione C14N ("http://www.w3.org/TR/2001/REC-xml-c14n-20010315"), l’algoritmo di firma il quale indica che è stata usata una coppia di chiavi asimmetriche di tipo RSA (“http://www.w3.org/2000/09/xmldsig#rsa-sha1”) ed infine Reference contiene l’algoritmo di hash utilizzato (“http://www.w3.org/2000/09/xmldsig#sha1") oltre al valore espresso in Base64 (/mTHMHggNBeZJV8ToGqQwNkgs9s) della parte di documento XML da firmare referenziato tramite l’attributo URI=”#Persone”.

Tornando agli elementi che compongono ds:Signature troviamo l’elemento SignatureValue il quale semplicemente contiene la firma digitale vera e propria dell’elemento SignedInfo espressa in Base64. Quindi [XMLDSIG] concepisce la firma di uno o più documenti raccogliendo tutte le informazioni all’interno dell’elemento SignedInfo (riferimenti ai dati da firmare interni allo stesso documento o esterni, gli algoritmi di hash e gli stessi hash) ed infine, firma direttamente SignedInfo utilizzando l’algoritmo di canonicalizzazione e di firma specificati. Nell’esempio precedente  il valore espresso in SignatureValue è quindi il prodotto della seguente sequenza:

Firma_rsa-sha1(C14N(SignedInfo))

Infine l’elemento opzionale KeyInfo permette di specificare come ottenere la chiave necessaria alla verifica del messaggio. Questo elemento è opzionale in quanto in alcuni scenari le informazioni sulle chiavi fanno parte del contesto applicativo e la specifica, come detto in precedenza, non vuole dare nessuna restrizione alle applicazioni.
Lo schema di KeyInfo :

<element name="KeyInfo" type="ds:KeyInfoType"/>
 
<complexType name="KeyInfoType" mixed="true">
  
<choice maxOccurs="unbounded">
     
<element ref="ds:KeyName"/>
     
<element ref="ds:KeyValue"/>
     
<element ref="ds:RetrievalMethod"/>
     
<element ref="ds:X509Data"/>
     
<element ref="ds:PGPData"/>
     
<element ref="ds:SPKIData"/>
     
<element ref="ds:MgmtData"/>
     
<any processContents="lax" namespace="##other"/>
     
<!-- (1,1) elements from (0,unbounded) namespaces -->
   
</choice>
   
<attribute name="Id" type="ID" use="optional"/>
</complexType>

dimostra che sono contemplati vari tipi di KeyInfo. In aggiunta a questi tipi ai quali è stata associata una struttura XML [XMLDSIG] prevede un ulteriore formato, chiamato rawX509Certificate, che permette di gestire un certificato X509 (binario) codificato in ASN.1 DER. Nel nostro esempio utilizziamo semplicemente l’elemento KeyValue al cui interno è contenuta la chiave pubblica RSA espressa tramite <Modulus> e <Exponent>.

La fase di verifica della firma digitale avviene in due fasi :

  1. la verifica degli hash contenuti all’interno di ogni Reference 
  2. la verifica della firma applicata all’elemento SignedInfo.

La prima fase prevede la normalizzazione di tutto SignedInfo secondo l’algoritmo espresso in CanonicalizationMethod presente sempre nello stesso SignedInfo. In seguito, per ogni elemento Reference si ottiene il documento da verificare tramite l’attributo URI, gli si applicano eventuali trasformazioni, si calcola l’hash utilizzando l’algoritmo identificato in DigestMethod ed infine lo si paragona con il valore salvato in DigestValue.

Nella seconda fase invece si ottengono le informazioni riguardanti le chiavi crittografiche e si verifica la firma digitale applicata all’elemento SignedInfo tramite l’algoritmo specificato in SignatureMethod.

L’analisi della specifica [XMLDSIG] in questo contesto non è completa ma è sufficiente per introdurre WS-Security, la specifica di base per la sicurezza dei Web Services standardizzata da OASIS.

--Mario

Comments (2)

  1. La notizia di una futura disponibilità dei sorgenti di alcune librerie del framework .NET 3.5 era già

  2. La notizia di una futura disponibilità dei sorgenti di alcune librerie del framework .NET 3.5 era già

Skip to main content