IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

NodeJS Discussion :

Application client/serveur TLS


Sujet :

NodeJS

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 29
    Par défaut Application client/serveur TLS
    Bonjour à tous, je me tourne vers vous aujourd'hui car je fais face à un problème dont je ne parviens pas à trouver de solution.

    Je souhaite réaliser une application client/server avec node JS par l'élaboration d'un client serveur TCP. Souhaitant que tous les transfèrent de données se face de manière sécurisée, je vais donc utiliser TLS. Je me suis basé sur la doc officiel de Node.js concernant TLS mais en essayant de mettre en application l'exemple de client/seveur qu'il montre je ne parviens pas à le faire fonctionner.

    En effet je bloque sur la partie des clefs de sécurités, je ne parviens pas à créer des pairs de clés auto-signées qui fonctionnent, à chaque fois j'ai une erreur…

    Voici les codes dont je me suis servis :

    Server.js :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    const tls = require('tls');
    const fs = require('fs');
     
    const options = {
      key: fs.readFileSync('server-key.pem'),
      cert: fs.readFileSync('server-cert.pem'),
     
      // This is necessary only if using the client certificate authentication.
      requestCert: true,
     
      // This is necessary only if the client uses the self-signed certificate.
      ca: [ fs.readFileSync('client-cert.pem') ]
    };
     
    const server = tls.createServer(options, (socket) => {
      console.log('server connected',
                  socket.authorized ? 'authorized' : 'unauthorized');
      socket.write('welcome!\n');
      socket.setEncoding('utf8');
      socket.pipe(socket);
    });
    server.listen(8000, () => {
      console.log('server bound');
    });
    Client.js :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    const tls = require('tls');
    const fs = require('fs');
     
    const options = {
      // Necessary only if using the client certificate authentication
      key: fs.readFileSync('client-key.pem'),
      cert: fs.readFileSync('client-cert.pem'),
     
      // Necessary only if the server uses the self-signed certificate
      ca: [ fs.readFileSync('server-cert.pem') ]
    };
     
    const socket = tls.connect(8000, options, () => {
      console.log('client connected',
                  socket.authorized ? 'authorized' : 'unauthorized');
      process.stdin.pipe(socket);
      process.stdin.resume();
    });
    socket.setEncoding('utf8');
    socket.on('data', (data) => {
      console.log(data);
    });
    socket.on('end', () => {
      server.close();
    });
    Voici l'erreur qui m'est retourné lorsque le client ce connecte au serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    events.js:141
          throw er; // Unhandled 'error' event
          ^
     
    Error: Hostname/IP doesn't match certificate's altnames: "Host: localhost. is not cert's CN: CA"
        at Object.checkServerIdentity (tls.js:186:15)
        at TLSSocket.<anonymous> (_tls_wrap.js:1023:29)
        at emitNone (events.js:67:13)
        at TLSSocket.emit (events.js:166:7)
        at TLSSocket._init.ssl.onclienthello.ssl.oncertcb.TLSSocket._finishInit (_tls_wrap.js:582:8)
        at TLSWrap.ssl.onclienthello.ssl.oncertcb.ssl.onnewsession.ssl.onhandshakedone (_tls_wrap.js:424:38)
    Coté serveur voici ce qui est affiché :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    server bound
    server connected authorized
    Quelqu'un aurait-il une solution ? Car là je sèche dessus depuis plusieurs jours…


    Respectueusement,

    Yoratheon

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 29
    Par défaut
    Bonjour,

    Je suis finalement parvenu à résoudre mon problème en me basant sur un poste sur un blogue pour la génération des clés et certificats auto-signés (Using client certs in node.js).

    Voici un script que j'ai créé se basant sur ce qui est dit dans le poste du blogue précédemment cité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    #!/bin/bash
    if test $# -ne 3
    then
        echo "Wrong number of arguments"
        exit 1
    fi
     
    ROOTPATH="$1"
    FQDN=$2
    PASSWORD=$3
    RSABITS=4096
     
    # make directories to work from
    mkdir -p $ROOTPATH/certs/{server,client,ca,tmp}
     
    PATH_CA=$ROOTPATH/certs/ca
    PATH_SERVER=$ROOTPATH/certs/server
    PATH_CLIENT=$ROOTPATH/certs/client
    PATH_TMP=$ROOTPATH/certs/tmp
     
    ######
    # CA #
    ######
     
    openssl genrsa -des3 -passout pass:$PASSWORD -out $PATH_TMP/ca.key $RSABITS
     
    # Create Authority Certificate
    openssl req -new -x509 -days 365 -key $PATH_TMP/ca.key -out $PATH_CA/ca.crt -passin pass:$PASSWORD -subj "/C=FR/ST=./L=./O=ACME Signing Authority Inc/CN=."
     
    ##########
    # SERVER #
    ##########
     
    # Generate server key
    openssl genrsa -out $PATH_SERVER/server.key $RSABITS
     
    # Generate server cert
    openssl req -new -key $PATH_SERVER/server.key -out $PATH_TMP/server.csr -passout pass:$PASSWORD -subj "/C=FR/ST=./L=./O=ACME Signing Authority Inc/CN=$FQDN"
     
    # Sign server cert with self-signed cert
    openssl x509 -req -days 365 -passin pass:$PASSWORD -in $PATH_TMP/server.csr -CA $PATH_CA/ca.crt -CAkey $PATH_TMP/ca.key -set_serial 01 -out $PATH_SERVER/server.crt
     
    ##########
    # CLIENT #
    ##########
     
    openssl genrsa -out $PATH_CLIENT/client.key $RSABITS
     
    openssl req -new -key $PATH_CLIENT/client.key -out $PATH_TMP/client.csr -passout pass:$PASSWORD -subj "/C=FR/ST=./L=./O=ACME Signing Authority Inc/CN=CLIENT"
     
    openssl x509 -req -days 365 -passin pass:$PASSWORD -in $PATH_TMP/client.csr -CA $PATH_CA/ca.crt -CAkey $PATH_TMP/ca.key -set_serial 01 -out $PATH_CLIENT/client.crt
     
    exit 0
    Voici le code du serveur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    #!/usr/bin/env node
    'use strict';
     
    const tls = require('tls');
    const fs = require('fs');
    const port = 8000;
     
    const options = {
        key: fs.readFileSync('certs/server/server.key'),
        cert: fs.readFileSync('certs/server/server.crt'),
        ca: fs.readFileSync('certs/ca/ca.crt'), // authority chain for the clients
        requestCert: true, // ask for a client cert
        //rejectUnauthorized: false, // act on unauthorized clients at the app level
    };
     
    var server = tls.createServer(options, (socket) => {
      socket.write('welcome!\n');
      socket.setEncoding('utf8');
      socket.pipe(socket);
    })
     
    .on('connection', function(c)
    {
    	console.log('insecure connection');
    })
     
    .on('secureConnection', function (c)
    {
    	// c.authorized will be true if the client cert presented validates with our CA
    	console.log('secure connection; client authorized: ', c.authorized);
    })
     
    .listen(port, function() {
    	console.log('server listening on port ' + port + '\n');
    });
    Et le code du client :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    #!/usr/bin/env node
    'use strict';
     
    const port = 8000;
    const hostname = 'localhost';
     
    const tls = require('tls');
    var fs = require('fs');
     
    const options = {
      host: hostname,
      port: port,
     
      // Necessary only if using the client certificate authentication
      key: fs.readFileSync('certs/client/client.key'),
      cert: fs.readFileSync('certs/client/client.crt'),
     
      // Necessary only if the server uses the self-signed certificate
      ca: fs.readFileSync('certs/ca/ca.crt')
    };
     
    var socket = tls.connect(options, () => {
      console.log('client connected',
                  socket.authorized ? 'authorized' : 'unauthorized');
      process.stdin.pipe(socket);
      process.stdin.resume();
     
      socket.end();
    })
     
    .setEncoding('utf8')
     
    .on('data', (data) => {
      console.log(data);
    })
     
    .on('end', () => {
      console.log("End connection");
    });
    Lors de l'exécution du serveur et d'un client, la trace côté serveur est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    server listening on port 8000
     
    insecure connection
    secure connection; client authorized:  true
    Et côté client on obtient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    client connected authorized
    End connection
    Tout fonctionne parfaitement bien, je parviens à avoir une connexion sécurisée entre un client et un serveur avec un certificat auto-signé.

    J'ai créé un projet GitHub pour tout centraliser : Simble TLS Client/Server with Node.js

  3. #3
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    En Dev pour être plus proche de la réalité de la production, je n'utilise jamais de certificat autosigné. sauf....

    la solution est relativement simple
    je me suis créé une autorité de certification (à partir d'un certificat autosigné d'où le sauf)

    Pour les applications qui on besoin d'un certificat comme ton serveur. je créé le certificat et je le signe avec mon autorité.
    il suffit d'approuver la clef de l'autorité pour que tout fonctionne.

    Cela ne semble pas être bien différent que d'auto signer directement le certificat.

    la différence vient du fait que certain outil refuse les certificats autosigné (considéré comme dangereux)
    en approuvant l'autorité de tel outil voient que le certificat est signé par une autorité et demande au système de la vérifier. l'autorité étant approuvée le certificat est valide.

    ça ne coûte donc pas beaucoup. il suffit de créer une fois l'autorité pour toutes l'équipe de dev et pour tous les dev. de l'approuver
    ensuite pour chaque serveur ou appli créer un certificat et le signer.
    A+JYT
    https://jamielinux.com/docs/openssl-...ate-authority/

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Free Pascal] Application client/serveur en Pascal
    Par zouzou_zaza dans le forum Free Pascal
    Réponses: 15
    Dernier message: 02/09/2004, 17h57
  2. [Débutant] Application client serveur
    Par dk dans le forum Plateformes (Java EE, Jakarta EE, Spring) et Serveurs
    Réponses: 7
    Dernier message: 30/06/2004, 11h38
  3. Choix port pour application client-serveur
    Par Tiaps dans le forum Développement
    Réponses: 7
    Dernier message: 15/03/2004, 09h49
  4. Réponses: 2
    Dernier message: 01/10/2002, 12h25
  5. Langage le mieux adapté pour application client serveur ?
    Par guenus dans le forum Débats sur le développement - Le Best Of
    Réponses: 4
    Dernier message: 17/06/2002, 15h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo