CardSpace sans SSL : considérations d'implémentation

by Administrator 11. March 2008 19:19

Comme annoncé, voici quelques notes et réflexions sur l'implémentation de CardSpace sans SSL

Pour quelles utilisations ?

Lorsque vous allez sur un site Web utilisant Cardspace, il vous demande de choisir une carte. Lorsque vous avez fait ce choix, un ensemble d'informations est transmis au site Web (sous la forme d'un document XML). Si vous utilisez CardSpace sans SSL, ces données transitent en clair entre le client et le serveur, et l'identité du serveur n'est pas vérifiable. Pour ces raisons, vous ne pourrez échanger que des cartes auto-proclamées, qui comportent un sous-ensemble des informations suivantes :

  • Identifiant unique sur le site concerné
  • Prénom
  • Nom
  • Email
  • Adresse (rue)
  • Adresse (Ville)
  • Adresse (Département/province)
  • Code Postal
  • Pays/Région
  • Téléphone
  • Téléphone 2
  • Téléphone mobile
  • Date de naissance
  • Sexe

En d'autres termes, vous pouvez pré-remplir une fiche utilisateur avec ces informations, et reposer sur l'identifiant unique en remplacement d'un login/mot de passe. Ces informations sont relativement peu sensibles et ne serviront pas à grand-chose si elles sont interceptées pendant la communication avec le serveur.

En résumé : l'utilisation de CardSpace sans SSL est adaptée au login sur un site Web ne manipulant pas d'informations sensibles sur votre compte.

Que se passe-t-il lorsque j'utilise une carte personnelle sur un site Web ?

Au lieu d'utiliser une demande de login / mot de passe, le site Web vous demande d'envoyer les informations vous concernant.

Dans un premier temps, le site web vous demande de sélectionner une carte vous représentant, et vous indique quelles sont les données qu'il va demander :

imageDans cet exemple, le site a juste besoin de mon prénom (pour personnaliser les pages) et de mon identifiant sur le site (pour remplacer un login et un mot de passe).

Lorsque vous envoyez les données demandées, voici ce qui est transmis au site Web :

 

 

image

Les données transmises sont manifestement très simples à décoder, puisqu'une requête XPath donne directement accès aux informations voulues :

Public Function RecupereAttribut(ByVal jeton As String, ByVal claimName As String) As String
    Dim x As New System.Xml.XmlDocument()
    x.LoadXml(jeton)
    Dim xns As New XmlNamespaceManager(x.NameTable)
    xns.AddNamespace("saml", "urn:oasis:names:tc:SAML:1.0:assertion")
    Dim xn As System.Xml.XmlNode
    xn = x.SelectSingleNode("/saml:Assertion/saml:AttributeStatement/saml:Attribute[@AttributeName='" & claimName & "']", xns)
    Return xn.InnerText
End Function

Il y cependant quelques précautions à prendre pour garantir que personne ne pourra  se faire passer pour un de vos utilisateurs.

 

Que doit faire un site Web quand vous lui envoyez vos informations ?

La première chose à faire est de vérifier que le XML envoyé n'a pas été modifié par un utilisateur malveillant. Comme le document XML contient une balise <Signature>, il suffit de vérifier que la signature correspond bien au document transmis. Voici comment faire en VB.Net :

 

Public Function JetonValide(ByVal token As String) As Boolean
     ' charger le jeton
     Dim x As New XmlDocument()
     x.LoadXml(token)
     Dim s As New SamlSignedXml(x)
     ' renseigner les namespaces
     Dim xns As New XmlNamespaceManager(x.NameTable)
     xns.AddNamespace("sig", "http://www.w3.org/2000/09/xmldsig#")
     'vérifier la signature
     s.LoadXml(x.SelectSingleNode("//sig:Signature", xns))
     Return s.CheckSignature
End Function 

 

Ce code repose sur une classe SamlSignedXml qui est *presque* fournie par le Framework .Net (voir code source joint à la fin de cet article). Si vous n'êtes pas en .Net sur votre serveur Web il vous suffit de trouver un bout de code vérifiant une signature XML.

 

image

Une fois que vous êtes certain que le document XML n'a pas été modifié avant d'arriver sur le serveur, vous allez en extraire l'identifiant utilisateur qui remplace le login / mot de passe. Cet identifiant est en fait composé de deux parties : d'une part l'information PrivatePersonalIdentifier transmise dans le document XML, et l'information Modulus qui garantit que l'information vient bien du bon utilisateur. Pour ne pas avoir à stocker deux informations distinctes, le plus simple est de les combiner et d'en faire votre identifiant utilisateur :

 

Public Function IDUtilisateur(ByVal jeton As String) As String
    ' Récupération du PPID
    Dim PPID As String = RecupereAttribut(jeton, "privatepersonalidentifier") 

    ' Récupération de la clé
    Dim x As New XmlDocument()
    x.LoadXml(jeton)
    Dim xns As New XmlNamespaceManager(x.NameTable)
    xns.AddNamespace("sig", "http://www.w3.org/2000/09/xmldsig#")
    Dim ClePublique As String = x.SelectSingleNode("//sig:Modulus", xns).InnerText 

    'Combinaison des deux données en une seule
    Dim hacheur As SHA1 = SHA1.Create("SHA1")
    Dim OctetsPPID() As Byte = Convert.FromBase64String(PPID)
    Dim OctetsCle() As Byte = Convert.FromBase64String(ClePublique)
    Dim OctetsAHacher(OctetsPPID.Length + OctetsCle.Length) As Byte
    OctetsPPID.CopyTo(OctetsAHacher, 0)
    OctetsCle.CopyTo(OctetsAHacher, OctetsPPID.Length) 

    'Transformation en chaine de caractères
    Return Convert.ToBase64String(hacheur.ComputeHash(OctetsAHacher))
End Function 

 

Et pour les plus flemmards...

Vous trouverez dans CardSpaceSansSSL.Zip 4 fichiers :

PageNormale.html et ic_image.jpg : l'image et l'exemple de code HTML nécessaires pour utiliser Cardspace sur n'importe quel site.

decodejeton.aspx et decodejeton.aspx.vb : une page de test qui affiche les informations transmises après avoir vérifié leur validité.

CardSpaceSansSSL.zip (9,74 KB)

Tags:

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading