2009-12-20 18 views
15

Al lavoro abbiamo un'app Web che dovremo interfacciare con l'app Web di un'altra azienda utilizzando Single Sign On convalidato da SAML. Le nostre app Web sono scritte in PHP ed è ovviamente irrilevante quale sia la lingua scelta dall'altra azienda. Tuttavia, ho avuto bisogno di scrivere una semplice API che quest'altra azienda possa inviare richieste SOAP con richieste SAML e generare una risposta SAML. Lo sto scrivendo da zero per tre motivi: 1) non sembrano esserci molte opzioni per le interazioni SAML scritte in PHP anche se volevo uno, 2) limita il sovraccarico che sarebbe coinvolto con l'aggiunta di un altro componente di terze parti e 3) creare le cose da zero di solito mi lascia una comprensione significativamente migliore e mi rende molto più capace di adattare la cosa in futuro, se necessario.Cosa devo sapere sulle firme XML per far funzionare SAML?

Ad ogni modo, sono abbastanza nuovo rispetto agli standard SAML, SOAP e XML in generale, quindi mi sono sempre insegnato come me stesso. L'API è praticamente completa per i nostri scopi, con l'unica eccezione che l'altra azienda ha specificato che la nostra risposta dovrà essere firmata digitalmente con un certificato (e la richiesta che riceveremo sarà analogamente firmata digitalmente). Quindi ho cercato di capire come elaborare/generare le firme XML, ma onestamente è un po 'confuso dato che le specifiche del W3C non sono esattamente leggere.

sezione 5.4.8 del documento Assertions and Protocol for the OASIS Security Markup Language (SAML) V1.1 (il documento Vado fuori, come l'altra società ha detto che verrà usato v1.1) include un esempio di una risposta firmata contenente un'affermazione firmata, che ho includerò qui per fare riferimento:

<Response IssueInstant="2003-04-17T00:46:02Z" MajorVersion="1" MinorVersion="1" 
Recipient="www.opensaml.org" ResponseID="_c7055387-af61-4fce-8b98-e2927324b306" 
xmlns="urn:oasis:names:tc:SAML:1.0:protocol" 
xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    <ds:SignedInfo> 
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> 
    <ds:Reference URI="#_c7055387-af61-4fce-8b98-e2927324b306"> 
    <ds:Transforms> 
    <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> 
    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> 
     <InclusiveNamespaces PrefixList="#default saml samlp ds xsd xsi" 
     xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
    </ds:Transform> 
    </ds:Transforms> 
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
    <ds:DigestValue>TCDVSuG6grhyHbzhQFWFzGrxIPE=</ds:DigestValue> 
    </ds:Reference> 
    </ds:SignedInfo> 
    <ds:SignatureValue>x/GyPbzmFEe85pGD3c1aXG4Vspb9V9jGCjwcRCKrtwPS6vdVNCcY5rHaFPYWkf+5EIYcPzx+pX1h43SmwviCqXRjRtMANWbHLhWAptaK1ywS7gFgsD01qjyen3CP+m3Dw6vKhaq1ed10BYyrIzb4KkHO4ahNyBVXbJwqv5pUaE4=</ds:SignatureValue> 
    <ds:KeyInfo> 
    <ds:X509Data> 
    <ds:X509Certificate>MIICyjCCAjOgAwIBAgICAnUwDQYJKoZIhvcNAQEEBQAwgakxCzAJBgNVBAYTA1VT ... 8I3bsbmRAUg4UP9hH6ABVq4KQKMknxu1xQxLhpR1y1GPdiowMNTrEG8cCx3w/w==</ds:X509Certificate> 
    </ds:X509Data> 
    </ds:KeyInfo> 
</ds:Signature> 
<Status><StatusCode Value="samlp:Success"/></Status> 
<Assertion AssertionID="_a75adf55-01d7-40cc-929f-dbd8372ebdfc" 
    IssueInstant="2003-04-17T00:46:02Z" Issuer="www.opensaml.org" 
    MajorVersion="1" MinorVersion="1" xmlns="urn:oasis:names:tc:SAML:1.0:assertion" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Conditions NotBefore="2003-04-17T00:46:02Z" NotOnOrAfter="2003-04-17T00:51:02Z"> 
    <AudienceRestrictionCondition> 
    <Audience>http://www.opensaml.org</Audience> 
    </AudienceRestrictionCondition> 
    </Conditions> 
    <AuthenticationStatement AuthenticationInstant="2003-04-17T00:46:00Z" 
    AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password"> 
    <Subject> 
    <NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">[email protected]</NameIdentifier> 
    <SubjectConfirmation> 
    <ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</ConfirmationMethod> 
    </SubjectConfirmation> 
    </Subject> 
    <SubjectLocality IPAddress="127.0.0.1"/> 
    </AuthenticationStatement> 
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    <ds:SignedInfo> 
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> 
    <ds:Reference URI="#_a75adf55-01d7-40cc-929f-dbd8372ebdfc"> 
    <ds:Transforms> 
     <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> 
     <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> 
     <InclusiveNamespaces PrefixList="#default saml samlp ds xsd xsi" 
     xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/> 
     </ds:Transform> 
    </ds:Transforms> 
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
    <ds:DigestValue>Kclet6XcaOgOWXM4gty6/UNdviI=</ds:DigestValue> 
    </ds:Reference> 
    </ds:SignedInfo> 
    <ds:SignatureValue>hq4zk+ZknjggCQgZm7ea8fI79gJEsRy3E8LHDpYXWQIgZpkJN9CMLG8ENR4Nrw+n7iyzixBvKXX8P53BTCT4VghPBWhFTSt9tHWu/AtJfOTh6qaAsNdeCyG86jmtp3TDMWuL/cBUj2OtBZOQMFn7jQ9YB7k1Iz3RqVL+wNmeWI4=</ds:SignatureValue> 
    <ds:KeyInfo> 
    <ds:X509Data> 
    <ds:X509Certificate>MIICyjCCAjOgAwIBAgICAnUwDQYJKoZIhvcNAQEEBQAwgakxCzAJBgNVBAYTA1VT ... 8I3bsbmRAUg4UP9hH6ABVq4KQKMknxu1xQxLhpR1y1GPdiowMNTrEG8cCx3w/w==</ds:X509Certificate> 
    </ds:X509Data> 
    </ds:KeyInfo> 
    </ds:Signature> 
</Assertion> 
</Response> 

Quindi, come faccio a generare qualcosa di simile? E se ricevo qualcosa di simile, come posso convalidarlo? Inoltre, qualcuno può offrire solo una panoramica concettuale di base di ciò che i tag <ds:Signature> sono qui? Sembra che ci siano due tag <ds:Signature>, uno nel principale <Response> e uno nel <Assertion>, ciascuno contenente il proprio <ds:DigestValue>, <ds:SignatureValue> e <ds:X509Certificate> (e ciascuno distinto). Come vengono generati? Qualsiasi luce su cui potresti versare questo sarà molto apprezzata. Esercitazioni o esempi di codice sarebbero ancora più apprezzati! Ma a questo punto, se riesci solo a mettermi sulla strada giusta, è tutto ciò che chiedo davvero. In questo momento tutto mi sembra ancora una grande scatola nera.

A proposito, se questo aiuta, si dice in altre parti del SAML 1.1 spec che le implementazioni SAML dovrebbero utilizzare il metodo "Exclusive canonica" solo (escl-C14N) e usano il "avvolgeva trasformare" solo. Non sono ancora completamente sicuro di cosa significhi.

risposta

27

firme elaborazione XML non è davvero troppo difficile, se siete molto familiare con XML, ma ci sono molti dettagli che devono essere assolutamente corretti o che le cose non funzionano, quindi probabilmente non proverei a scrivere la mia implementazione in questa situazione (l'ho implementata parzialmente una volta, ma quello era per un scopo diverso e speciale, e comunque non era un'implementazione completa).

In ogni caso, non so molto di SAML, ma so di XML e firme XML, quindi forse posso farti un po 'cercando di rispondere alle tue domande.

Un elemento Signature fa riferimento a un pezzo specifico di un documento XML che è stato firmato digitalmente, nel suo elemento figlio SignedInfo. L'elemento figlio Reference di quello (penso che ci possano essere molti elementi Reference che vengono concatenati quando si formano i byte da firmare ma non ricordo più di sicuro) punta al contenuto tramite l'attributo URI. Gli elementi Transform descrivono le trasformazioni eseguite sul contenuto indicato prima di eseguirne l'hashing; sarà necessario esaminare le specifiche per capire come sono definiti gli algoritmi di trasformazione. L'elemento DigestMethod fornisce l'algoritmo hash da applicare ai byte che sono il risultato di questi algoritmi di trasformazione (si noti che uno di questi è sempre canonicalizzazione che converte l'XML in byte) e lo DigestValue fornisce il risultato di tale algoritmo di digest.

La firma reale è nell'elemento SignatureValue, ed è prodotto applicando canonica dell'elemento CanonicalizationMethod per produrre i byte e poi la firma questi byte con il SignatureMethod. L'elemento KeyInfo ti dice come trovare la chiave da usare.

Canonicalizzazione, che appare un paio di volte sopra, è semplicemente un modo per convertire un documento XML in byte in modo che i documenti XML "equivalenti" producano la stessa sequenza di byte. Ciò è richiesto in una firma digitale perché gli algoritmi funzionano su byte e XML possono passare attraverso un certo numero di intermediari che probabilmente interromperanno i byte originali ma manterranno l'equivalenza. E sono necessari diversi metodi di canonicalizzazione per le diverse situazioni: se gli elementi vengono estratti dai documenti e inseriti in altri, è necessaria una canonizzazione esclusiva che rimuove le definizioni dello spazio dei nomi non necessarie, ma in altri casi potrebbe non funzionare correttamente, quindi è necessaria la canonizzazione inclusiva, che conserva tutti gli spazi dei nomi in-scope.

Questa è solo la base. Esistono diverse opzioni su come produrre una firma XML e, se si desidera implementare un verificatore funzionante, è necessario considerarle tutte. Dato che sei nuovo in XML in generale, ti ripeto il mio consiglio di usare qualcosa che esiste già. È un'esperienza di apprendimento interessante implementare una specifica, ma spesso è una perdita di tempo se le implementazioni sono già disponibili.

+0

Quando si è specificato il ca algoritmo di nonicalizzazione nell'elemento del metodo di canonicalizzazione dell'elemento di informazioni firmato, perché dovresti specificarlo di nuovo nell'elemento transform? – Ashwin

+1

@Ashwin: Il 'CanonicalizationMethod' in 'SignedInfo' è ciò che viene applicato all'elemento' SignedInfo', qualsiasi canonicalizzazione nelle trasformazioni viene applicata al contenuto indicato, quindi si applicano a cose diverse, ed è per questo che entrambi sono necessari. Inoltre, il contenuto firmato non deve necessariamente essere XML, quindi la canonicalizzazione non è necessariamente applicabile. – JaakkoK

+0

grazie per quello :) C'è un'altra area in cui sono bloccato. Sono obbligato a usare xslt nell'elemento transforms. Non c'è un esempio su come usarlo in java. Se possibile, puoi fornire un codice di esempio o indicare un collegamento che utilizza xslt nelle firme xml con java. – Ashwin

2

C'è un esempio in xmlseclibs.php in SimpleSAML. Si affida al modulo openssl per eseguire la crittografia.

Vorrei sinceramente usare quella lib o ponte per Java/Tomcat, proprio perché i problemi di interoperabilità potrebbero venire che avrebbe bisogno di essere potenzialmente debug,

Problemi correlati