none
Le certificat « CN=XYZ, ..... » doit contenir une clé privée. Le processus doit disposer de droits d’accès à la clé privée. RRS feed

  • Question

  • Bonjour,

    Ce truc est en train de me rendre dingue.
    Je vous explique le contexte, histoire de gagner du temps.

    L'objectif est de s'authentifier auprès d'un service WCF distant et de mettre en place la sécurité de niveau Message entre le client
    WCF et le service WCF avec installation croisée de certificats.
    Mon client WCF est hébergé par un service Windows - qui tourne temporairement - sur le compte de l'administrateur par défaut du domaine
    MONDOMAINE\Administrateur
    Le service WCF est hébergé par IIS7/WAS.

    J'ai un problème avec la machine "cliente" du service, et en particulier donc avec l'accès à la clef privée du certificat.

    J'ai fait la demande de certificat depuis mon navigateur internet IE6 (...) depuis XP SP2, auprès d'un fournisseur de certificats (un broker).
    Ceci génère un CSR que je soumets dans le formulaire du fournisseur et une clef privée, c.à.d. un fichier qui est stocké dans un répertoire
    - dépendant de l'utilisateur qui a fait la demande - du type

    C:\Documents and Settings\Administrateur.MONDOMAINE\Application Data\Microsoft\Crypto\RSA\S-1-5-21-850011111-5498301895-1111276999-500\
    65elkjfgfdlkj6552372e0dmlk654ca35_1+654654-654a-6541-9c45-6574f654f6

    Mon service Windows qui héberge mon client WCF (vous me suivez ?) tourne bien sur le même compte qui a fait la demande de certificat.
    J'ai donné accès à ce compte à la clef privée du certificat via les outils FindPrivateKey et cacls, ou mieux, via WSE X509 Certificat Tool.

    J'ai installé le certificat client dans le magasin LocalMachine/My (Ordinateur local/Personnel) puisqu'il s'agissait d'authentifier une machine et non un utilisateur.

    Je démarre mon service Windows, ce qui lance le client WCF... et miracle, tout marche bien, et l'application fait ce qu'elle doit faire ...etc.
    Le tout traite environ 5 messages/seconde en remontant des fichiers de 50ko sur la plateforme distante.

    Le truc tourne toute la journée et envoie les 30 000 fichiers en attente de traitement qui se trouvaient sur la machine cliente.
    J'arrête le service parce que nous sommes en attente d'infos pour un truc particulier...
    Le lendemain, je bricole 2 ou 3 trucs ... et...rien ne va plus ...
    Le message d'erreur est le suivant.

    Échec de la négociation de sécurité SOAP. Pour plus d'informations, voir l'exception interne.

    ...
    System.ServiceModel.Security.SecurityNegotiationException: Échec de la négociation de sécurité SOAP. Pour plus d'informations, voir l'exception interne. ---> System.ArgumentException: Le certificat " CN=XYZ..." doit contenir une clé privée. Le processus doit disposer de droits d'accès à la clé privée.
       à System.ServiceModel.Security.TlsSspiNegotiation.ValidateClientCertificate()
       à System.ServiceModel.Security.TlsSspiNegotiation..ctor(String destination, Boolean isServer, SchProtocols protocolFlags, X509Certificate2 serverCertificate, X509Certificate2 clientCertificate, Boolean clientCertRequired)
       à System.ServiceModel.Security.TlsnegoTokenProvider.CreateTlsSspiState(X509SecurityToken token)
       à System.ServiceModel.Security.TlsnegoTokenProvider.CreateNegotiationState(EndpointAddress target, Uri via, TimeSpan timeout)
       à System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
       --- Fin de la trace de la pile d'exception interne ---


    Donc : Le certificat " CN=XYZ, ..... " doit contenir une clé privée. Le processus doit disposer de droits d'accès à la clé privée.

    Comment est-ce possible ? Le service démarre avec un compte qui a bien accès en lecture à la clef privée...
    Voyez-vous une raison à ceci ?

    Question subsidiaire pour départager les vainqueur ;-)

    Dans l'idéal, mon service Windows devrait tourner avec le service réseau. Donc un compte système avec des privilèges restreints
    Demander un certificat revient à fournier un CSR à un fournisseur de certificats, et celui-ci construit le certificat à partir de ce CSR.
    Or puisque qu'IE génère ce CSR alors que je suis connecter sur un compte admis, la clef privée s'installe dans un dossier
    appartenant à l'utilisateur connecté :

    C:\Documents and Settings\Utilisateur_connecté\Application Data\Microsoft\Crypto\...

    Or j'ai remarqué que dans tous les exemples fournis - en particulier avec FindPrivateKey - la clef privée se trouve dans un dossier ne dépendant pas de l'utilisateur courant :

    C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys\dfmlsdkfm65465....

    Ce qui est plus satisfaisant lorsqu'on veut sécuriser une machine.

    J'en viens à ma question : comment peut-on générer un CSR autrement que par IE pour sécuriser un service WCF.

    D'avance merci de votre aide !!

    Damien

    lundi 1 février 2010 15:12

Toutes les réponses

  • Bonjour,

    Utilisez la console MMC et ajoutez le composant "Certificats" pour gérer les certificats sans passer par IE.
    Lancez la console MMC via la commande RUNAS avec le compte sur lequel tourne votre service (ou loguer vous avec ce compte).

    Il est fortement déconseillé de faire tourner vos services sur le compte Service Réseau.

    Cordialement
    Gilles TOURREAU - MVP C# - Architecte .NET/Consultant/Formateur
    dimanche 14 mars 2010 22:31
    Modérateur