2016-11-25 68 views
0

我想創建下使用OpenSSL的這麼一個加密聊天服務器上創建聊天服務器,已經採取了代碼:http://simplestcodings.blogspot.in/2010/08/secure-server-client-using-openssl-in-c.html如何使用OpenSSL的在C

我想這個代碼轉換爲並行聊天服務器,但如何能我那樣做?

當我嘗試客戶端與服務器的連接,它只是顯示:

在服務器端:

Connection: 127.0.0.1:34902 
No certificates. 
Client msg: "Hello???" 

在客戶端:

Connected with AES256-GCM-SHA384 encryption 
Server certificates: 
Subject: /C=IN/ST=UK/L=DDN/O=UPES/OU=IT/CN=KAVIN/[email protected] 
Issuer: /C=IN/ST=UK/L=DDN/O=UPES/OU=IT/CN=KAVIN/[email protected] 
Received: "<html><body><pre>Hello???</pre></body></html> 

" 

我希望做一個客戶端和服務器之間的加密聊天

server.c

#include <stdio.h> 
#include <errno.h> 
#include <unistd.h> 
#include <malloc.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <resolv.h> 
#include <netdb.h> 
#include <openssl/ssl.h> 
#include <openssl/err.h> 

#define FAIL -1 

int OpenConnection(const char *hostname, int port) 
{ int sd; 
    struct hostent *host; 
    struct sockaddr_in addr; 

    if ((host = gethostbyname(hostname)) == NULL) 
    { 
     perror(hostname); 
     abort(); 
    } 
    sd = socket(PF_INET, SOCK_STREAM, 0); 
    bzero(&addr, sizeof(addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(port); 
    addr.sin_addr.s_addr = *(long*)(host->h_addr); 
    if (connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0) 
    { 
     close(sd); 
     perror(hostname); 
     abort(); 
    } 
    return sd; 
} 

SSL_CTX* InitCTX(void) 
{ SSL_METHOD *method; 
    SSL_CTX *ctx; 

    OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */ 
    SSL_load_error_strings(); /* Bring in and register error messages */ 
    method = TLSv1_2_client_method(); /* Create new client-method instance */ 
    ctx = SSL_CTX_new(method); /* Create new context */ 
    if (ctx == NULL) 
    { 
     ERR_print_errors_fp(stderr); 
     abort(); 
    } 
    return ctx; 
} 

void ShowCerts(SSL* ssl) 
{ X509 *cert; 
    char *line; 

    cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */ 
    if (cert != NULL) 
    { 
     printf("Server certificates:\n"); 
     line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); 
     printf("Subject: %s\n", line); 
     free(line);  /* free the malloc'ed string */ 
     line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); 
     printf("Issuer: %s\n", line); 
     free(line);  /* free the malloc'ed string */ 
     X509_free(cert);  /* free the malloc'ed certificate copy */ 
    } 
    else 
     printf("Info: No client certificates configured.\n"); 
} 

int main(int count, char *strings[]) 
{ SSL_CTX *ctx; 
    int server; 
    SSL *ssl; 
    char buf[1024]; 
    int bytes; 
    char *hostname, *portnum; 

    if (count != 3) 
    { 
     printf("usage: %s <hostname> <portnum>\n", strings[0]); 
     exit(0); 
    } 
    SSL_library_init(); 
    hostname=strings[1]; 
    portnum=strings[2]; 

    ctx = InitCTX(); 
    server = OpenConnection(hostname, atoi(portnum)); 
    ssl = SSL_new(ctx);  /* create new SSL connection state */ 
    SSL_set_fd(ssl, server); /* attach the socket descriptor */ 
    if (SSL_connect(ssl) == FAIL) /* perform the connection */ 
     ERR_print_errors_fp(stderr); 
    else 

    { char *msg = "Hello???"; 

     printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); 
     ShowCerts(ssl); 
     /* get any certs */ 
    while(1){ 
     SSL_write(ssl, msg, strlen(msg)); /* encrypt & send message */ 
     bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */ 
     buf[bytes] = 0; 
     printf("Received: \"%s\"\n", buf); 
     SSL_free(ssl);  /* release connection state */ 

} 
    close(server);   /* close socket */ 
    SSL_CTX_free(ctx);  /* release context */ 

    return 0; 
} 

Client.c

#include <stdio.h> 
#include <errno.h> 
#include <unistd.h> 
#include <malloc.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <resolv.h> 
#include <netdb.h> 
#include <openssl/ssl.h> 
#include <openssl/err.h> 

#define FAIL -1 

int OpenConnection(const char *hostname, int port) 
{ int sd; 
    struct hostent *host; 
    struct sockaddr_in addr; 

    if ((host = gethostbyname(hostname)) == NULL) 
    { 
     perror(hostname); 
     abort(); 
    } 
    sd = socket(PF_INET, SOCK_STREAM, 0); 
    bzero(&addr, sizeof(addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(port); 
    addr.sin_addr.s_addr = *(long*)(host->h_addr); 
    if (connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0) 
    { 
     close(sd); 
     perror(hostname); 
     abort(); 
    } 
    return sd; 
} 

SSL_CTX* InitCTX(void) 
{ SSL_METHOD *method; 
    SSL_CTX *ctx; 

    OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */ 
    SSL_load_error_strings(); /* Bring in and register error messages */ 
    method = TLSv1_2_client_method(); /* Create new client-method instance */ 
    ctx = SSL_CTX_new(method); /* Create new context */ 
    if (ctx == NULL) 
    { 
     ERR_print_errors_fp(stderr); 
     abort(); 
    } 
    return ctx; 
} 

void ShowCerts(SSL* ssl) 
{ X509 *cert; 
    char *line; 

    cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */ 
    if (cert != NULL) 
    { 
     printf("Server certificates:\n"); 
     line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); 
     printf("Subject: %s\n", line); 
     free(line);  /* free the malloc'ed string */ 
     line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); 
     printf("Issuer: %s\n", line); 
     free(line);  /* free the malloc'ed string */ 
     X509_free(cert);  /* free the malloc'ed certificate copy */ 
    } 
    else 
     printf("Info: No client certificates configured.\n"); 
} 

int main(int count, char *strings[]) 
{ SSL_CTX *ctx; 
    int server; 
    SSL *ssl; 
    char buf[1024]; 
    int bytes; 
    char *hostname, *portnum; 

    if (count != 3) 
    { 
     printf("usage: %s <hostname> <portnum>\n", strings[0]); 
     exit(0); 
    } 
    SSL_library_init(); 
    hostname=strings[1]; 
    portnum=strings[2]; 

    ctx = InitCTX(); 
    server = OpenConnection(hostname, atoi(portnum)); 
    ssl = SSL_new(ctx);  /* create new SSL connection state */ 
    SSL_set_fd(ssl, server); /* attach the socket descriptor */ 
    if (SSL_connect(ssl) == FAIL) /* perform the connection */ 
     ERR_print_errors_fp(stderr); 
    else 

    { char *msg = "Hello???"; 

     printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); 
     ShowCerts(ssl); 
     /* get any certs */ 
    while(1){ 
     SSL_write(ssl, msg, strlen(msg)); /* encrypt & send message */ 
     bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */ 
     buf[bytes] = 0; 
     printf("Received: \"%s\"\n", buf); 
     SSL_free(ssl);  /* release connection state */ 

} 
    close(server);   /* close socket */ 
    SSL_CTX_free(ctx);  /* release context */ 

    return 0; 
} 

請評論中的代碼爲改變正如您已經使用了SSL功能的代碼轉換爲加密的聊天服務器

回答

2

,您的聊天程序實際上是安全的。但是從您的帖子看來,您似乎希望增強安全連接。 爲了實現加密和解密,你可以試試,

//加密

AES_KEY encKey; 
AES_set_encrypt_key(key, 128, &encKey); 
AES_encrypt(text, out, &encKey); 

//解密

AES_KEY decKey; 
AES_set_decrypt_key(key,128,&decKey); 
AES_decrypt(out, text, &decKey); 

注:key應該是共同

+0

其實我想發送和接收靜音和服務器之間的消息,以便它可以像加密聊天應用程序一樣工作。因爲在上面的代碼中我無法發送和接收消息它只是說(「你好」) – kavin

+2

邏輯是加密「hello」消息,然後發送加密的消息。現在在使用公共密鑰的另一側,解密消息。如果任何欺詐/中間人攻擊進入,那麼加密的消息將被傳送。沒有公共密鑰就無法解密信息。這些是加密和解密的功能。你可以在你的代碼中使用它。 –

+0

這引出了一個問題:如何在兩個設備之間共享密鑰,以及如何對設備/人員進行身份驗證。 – zaph