none
Signature de fichier xml RRS feed

  • Question

  • Bonjour, je dois signer un fichier XML à l'aide d'un certificat avec l'extension CER et uniquement avec cette extension.
    Jusqu'à maintenant, je me servais du store pour mes signatures, histoire de voir comment cela pouvait fonctionnait et mon code marche très bien, mais quand je veux me servir d'un fichier externe, mon programme plante et j'ai comme erreur "la clé de signature n'est pas chargée".

    Je génère des certificats de manière auto-signée, à l'aide de l'invite de commende de visual studio et j'entre la commande :

    makecert -n "CN=..., O=..., OU=..., C=PE" moncertificat.cer

    Dans mon code qui génère la signature du fichier XML, j'utilise une fonction ayant comme paramètre :

    - param_nomfichier  de type string, contient le nom du fichier à signer sans l'extension

    - param_nomfichier  de type string, contient le nom du fichier qui va être utilisé pour signer, contient l'extension

    - param_pwdcert de type string,  contient le mot de passe du certificat utilisé.

    Ma fonction est codée ainsi:

    Dim xmlFile As String = "TEMP\" & param_nomfichier & ".xml"
    Dim certificattrouve As Boolean = False
     
    Dim MonCertificat As X509Certificate2 = New X509Certificate2(param_certificate, param_pwdcert)
     
     
    'signature
    'Tout d'abord, il faut commencer par charger notre fichier XML.
    Dim xmlDoc As XmlDocument = New XmlDocument()
    xmlDoc.PreserveWhitespace = True
    xmlDoc.Load(xmlFile)
     
    'Maintenant nous allons créer un objet SignedXml portant sur le document XML que l'on veut signer.
    Dim signedXml As SignedXml = New SignedXml(xmlDoc)
     
    'On renseigne la clé à utiliser pour signer en indiquant la clé privée de notre certificat.
    signedXml.SigningKey = MonCertificat.PrivateKey
     
    'Puis on ajoute ensuite les informations du certificat afin de pouvoir vérifier la signature.
    'Dans notre exemple, les informations du certificat seront sous la forme de balises X509Data
    Dim KeyInfo As KeyInfo = New KeyInfo()
     
    'On crée un objet Reference qui permet de préciser les informations à signer.
    'Pour signer l'ensemble du document on utilise une chaîne vide comme référence.
    Dim Reference As Reference = New Reference()
    Reference.Uri = ""
     
    'On va maintenant ajouter une transformation pour indiquer qu'il s'agit d'une signature enveloppée.
    'Cette étape est très importante car cela permet de ne pas tenir compte des éléments Signature déjà
    'présents pour le calcul de l'empreinte.
    Reference.AddTransform(New XmlDsigEnvelopedSignatureTransform())
     
    'On ajoute la référence à l'objet SignedXml.
    signedXml.AddReference(Reference)
     
    Dim X509Chain As X509Chain = New X509Chain()
    X509Chain.Build(MonCertificat)
    For Each element As X509ChainElement In X509Chain.ChainElements
        Dim x509Data As KeyInfoX509Data = New KeyInfoX509Data(element.Certificate)
        Dim issuer As String = element.Certificate.Issuer
        'Dim subjectName As String = element.Certificate.IssuerName.ToString()
        Dim subjectName As String = element.Certificate.IssuerName.Name
     
        x509Data.AddSubjectName(subjectName)
        KeyInfo.AddClause(x509Data)
    Next
     
    signedXml.KeyInfo = KeyInfo
    signedXml.ComputeSignature()
     
    'On calcule la signature et on récupère le XML associé. 
    Dim signature As XmlElement = signedXml.GetXml()
     
    'On ajoute à la fin du document XML la signature générée puis on sauvegarde le document ainsi modifié.
    For Each node As XmlNode In signature.SelectNodes("descendant-or-self::*[namespace-uri()='http://www.w3.org/2000/09/xmldsig#']")
        node.Prefix = "ds"
        If node.LocalName = "Signature" Then
            Dim newAttribute As XmlAttribute = xmlDoc.CreateAttribute("Id")
            newAttribute.Value = "SignatureSP"
            node.Attributes.Append(newAttribute)
            'node.InsertAfter(node, node.LastChild)
        End If
        ' MsgBox(node.LocalName)
    Next node
     
    xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(signature, True))
    xmlDoc.Save(xmlFile)

    et elle plante en arrivant sur cette ligne:

    signedXml.ComputeSignature()

    Mon problème viendrait-il du certificat en lui même? viendrait-il de mon code VB?

    Merci

    UPDATE: MonCertificat.PrivateKey n'a pas de valeur

    lundi 3 mars 2014 14:16

Réponses

  • Bonjour, j'ai pu trouver une solution à mon problème, à l'aide d'openssl, je génère un certificat CER et une clé KEY, je me sers des 2 pour produire un certificat PFX. Grâce à cela, je charge mon certificat PFX, ma clé privée est ainsi chargée et le processus de signature suit son cours sans soucis, merci quand même
    • Marqué comme réponse Aurel Bera jeudi 6 mars 2014 13:08
    jeudi 6 mars 2014 13:04

Toutes les réponses