2016-12-19 1 views
0

J'ai écrit un script, qui peut créer une connexion à un serveur HTTP et afficher le contenu du site Web dans la console. Très facile. Mais je veux me connecter à un serveur https et faire les mêmes procédures. J'ai cherché sur google et n'ai pas trouvé ce que j'ai cherché.OpenSSL en connexion Socket C++ (client HTTPS)

S'il vous plaît aidez-moi et donnez-moi un tutoriel qui puis-je utiliser la bibliothèque openssl.

Je me suis essayé sur la bibliothèque openssl, mais la bibliothèque est très compliquée et difficile à comprendre.

Voici mon code du client http:

#include <iostream> 
#include <ctype.h> 
#include <cstring> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <netinet/in.h> 
#include <unistd.h> 
#include <sstream> 
#include <fstream> 
#include <string> 
#include <arpa/inet.h> 
#include <openssl/ssl.h> 

using namespace std; 

int sock; 
struct sockaddr_in client; 
int PORT = 80; 

int main(int argc, char const *argv[]) 
{ 
    bzero(&client, sizeof(client)); 
    client.sin_family = AF_INET; 
    client.sin_port = htons(PORT); 
    client.sin_addr.s_addr = inet_addr("172.16.0.6"); 

    sock = socket(AF_INET, SOCK_STREAM, 0); 

    if (sock < 0) { 
     cout << "Error creating socket." << endl; 
     exit(1); 
    } 

    if (connect(sock, (struct sockaddr *)&client, sizeof(client)) < 0) { 
     close(sock); 
     cout << "Could not connect" << endl; 
     exit(1); 
    } 

    stringstream ss; 
    ss << "GET /" << "\r\n" 
    << "Host: 172.16.1.4\r\n" 
    << "Accept: application/json\r\n" 
    << "Connection: close" 
    << "\r\n\r\n"; 
    string request = ss.str(); 

    if (send(sock, request.c_str(), request.length(), 0) != (int)request.length()) { 
     cout << "Error sending request." << endl; 
     exit(1); 
    } 

    char cur; 
    while (read(sock, &cur, 1) > 0) { 
     cout << cur; 
    } 

    return 0; 
} 
+3

Oui, la bibliothèque OpenSSL est supérieure à la moyenne, en termes de complexité et de difficulté à utiliser. Non seulement vous devez savoir comment l'utiliser, mais vous devez aussi avoir une bonne connaissance de la technologie derrière SSL/TLS. Commencez à lire sa documentation. Obtenez un livre sur l'implémentation des applications SSL et commencez à lire ce livre. Non, il n'y a pas de raccourcis, et aucune baguette magique ne peut être supprimée, et faire sortir un client SSL de nulle part. Il n'y a pas d'autre choix que d'investir beaucoup de temps et d'efforts pour étudier et apprendre à utiliser la bibliothèque. –

+0

ouais je sais. une petite connaissance de TLS/SSL existe. Mais j'ai besoin d'une solution "rapide" pour le programme C++. Maintenant, j'ai trouvé un bon moyen: j'utilise la librairie libcurl. Voici déjà une implémentation HTTPS. Merci beaucoup! – Hball

+0

En utilisant OpenSSL, l'approche la plus simple serait de remplacer 'connect()', 'read()' et 'send()' par 'ssl_connect()', 'ssl_read()' et 'ssl_write()', respectivement. Cela signifie réécrire votre logique de socket existante, puisque HTTP et HTTPS utiliseront des chemins de code différents. Si vous voulez réutiliser votre code de socket existant et juste ajouter OpenSSL par dessus, vous pouvez utiliser l'API 'BIO' d'OpenSSL, ce qui vous permet de continuer à utiliser' connect() ',' read() 'et' send() ' , vous venez d'associer des tampons de mémoire dédiée pour gérer les données cryptées avant et en arrière. Il y a ** tonnes ** d'exemples si vous regardez autour. –

Répondre

1

Voici un exemple de client SSL qui se connecte à https://google.ru et imprime téléchargé une page: SSLClient.cpp

//============================================================================ 
// Name  : SSLClient.cpp 
// Compiling : g++ -c -o SSLClient.o SSLClient.cpp 
       g++ -o SSLClient SSLClient.o -lssl -lcrypto 
//============================================================================ 
#include <stdio.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <openssl/ssl.h> 
#include <openssl/err.h> 
using namespace std; 

SSL *ssl; 
int sock; 

int RecvPacket() 
{ 
    int len=100; 
    char buf[1000000]; 
    do { 
     len=SSL_read(ssl, buf, 100); 
     buf[len]=0; 
     printf(buf); 
    } while (len > 0); 
    if (len < 0) { 
     int err = SSL_get_error(ssl, len); 
     if (err == SSL_ERROR_WANT_READ) 
      return 0; 
     if (err == SSL_ERROR_WANT_WRITE) 
      return 0; 
     if (err == SSL_ERROR_ZERO_RETURN || err == SSL_ERROR_SYSCALL || err == SSL_ERROR_SSL) 
      return -1; 
    } 
} 

int SendPacket(const char *buf) 
{ 
    int len = SSL_write(ssl, buf, strlen(buf)); 
    if (len < 0) { 
     int err = SSL_get_error(ssl, len); 
     switch (err) { 
     case SSL_ERROR_WANT_WRITE: 
      return 0; 
     case SSL_ERROR_WANT_READ: 
      return 0; 
     case SSL_ERROR_ZERO_RETURN: 
     case SSL_ERROR_SYSCALL: 
     case SSL_ERROR_SSL: 
     default: 
      return -1; 
     } 
    } 
} 


void log_ssl() 
{ 
    int err; 
    while (err = ERR_get_error()) { 
     char *str = ERR_error_string(err, 0); 
     if (!str) 
      return; 
     printf(str); 
     printf("\n"); 
     fflush(stdout); 
    } 
} 


int main(int argc, char *argv[]) 
{ 
    int s; 
    s = socket(AF_INET, SOCK_STREAM, 0); 
    if (!s) { 
     printf("Error creating socket.\n"); 
     return -1; 
    } 
    struct sockaddr_in sa; 
    memset (&sa, 0, sizeof(sa)); 
    sa.sin_family  = AF_INET; 
    sa.sin_addr.s_addr = inet_addr("74.125.232.247"); // address of google.ru 
    sa.sin_port  = htons (443); 
    socklen_t socklen = sizeof(sa); 
    if (connect(s, (struct sockaddr *)&sa, socklen)) { 
     printf("Error connecting to server.\n"); 
     return -1; 
    } 
    SSL_library_init(); 
    SSLeay_add_ssl_algorithms(); 
    SSL_load_error_strings(); 
    const SSL_METHOD *meth = TLSv1_2_client_method(); 
    SSL_CTX *ctx = SSL_CTX_new (meth); 
    ssl = SSL_new (ctx); 
    if (!ssl) { 
     printf("Error creating SSL.\n"); 
     log_ssl(); 
     return -1; 
    } 
    sock = SSL_get_fd(ssl); 
    SSL_set_fd(ssl, s); 
    int err = SSL_connect(ssl); 
    if (err <= 0) { 
     printf("Error creating SSL connection. err=%x\n", err); 
     log_ssl(); 
     fflush(stdout); 
     return -1; 
    } 
    printf ("SSL connection using %s\n", SSL_get_cipher (ssl)); 

    char *request = "GET https://www.google.ru/intl/en/about/company/facts/ HTTP/1.1\r\n\r\n"; 
    SendPacket(request); 
    RecvPacket(); 
    return 0; 
} 

Notez que si vous voulez échange de données entre le client et le serveur avec openssl, vous devrez peut-être traiter les codes d'erreur SSL_ERROR_WANT_READ et SSL_ERROR_WANT_WRITE comme décrit dans la documentation. Mais ce n'est pas nécessaire ici car le protocole HTTPS est en série.