2012-09-17 206 views
0

我已經在網上找到了幾個教程編寫了一套簡單的SSL客戶端/服務器程序 - 而且這些工作正常。我無法得到我的頭是客戶端的東西(見下文)嘗試使用SSL連接

它看起來好像從客戶端連接到SSL服務器的代碼,盲目接受它提供的證書,然後用它來加密/解密發送和接收數據的數據。

是否應該沒有客戶端驗證服務器證書的使用?我的意思是我可以用任何新的服務器端證書來更換/交換服務器端證書,並讓它連接起來沒有那麼多潤色劑?這是一種安全的連接方式? (還是我 - 我懷疑 - 缺少的東西)

非常感謝

FR

void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile); 
int OpenConnection(const char *hostname, int port); 
void ShowCerts(SSL* ssl); 
SSL_CTX* InitCTX(void); 


int main(int count, char *strings[]) { 


    char *hostname, *portnum; 
    char buf[1024]; 
    SSL_CTX *ctx; 
    SSL *ssl; 
    int server; 
    int bytes; 


    if (count != 3) { 


     printf("usage: %s <hostname> <portnum>\n", strings[0]); 
     exit(0); 


    } // if 


    hostname=strings[1]; 
    portnum=strings[2]; 


    printf("\nSSL Client 0.1\n~~~~~~~~~~~~~~~\n\n"); 


    // Init. the SSL lib 
    SSL_library_init(); 
    ctx = InitCTX(); 


    printf("Client SSL lib init complete\n"); 


    // Open the connection as normal 
    server = OpenConnection(hostname, atoi(portnum)); 


    // Create new SSL connection state 
    ssl = SSL_new(ctx); 


    // Attach the socket descriptor 
    SSL_set_fd(ssl, server); 


    // Perform the connection 
    if (SSL_connect(ssl) != FAIL) { 


     char *msg = "Here is some data"; 


     printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); 

     // Print any certs 
     ShowCerts(ssl); 


     // Encrypt & send message */ 
     SSL_write(ssl, msg, strlen(msg)); 


     // Get reply & decrypt 
     bytes = SSL_read(ssl, buf, sizeof(buf)); 


     buf[bytes] = 0; 
     printf("Received: '%s'\n\n", buf); 


     // Release connection state 
     SSL_free(ssl); 


    } // if 


    else ERR_print_errors_fp(stderr); 


    // Close socket 
    close(server); 


    // Release context 
    SSL_CTX_free(ctx); 
    return 0; 


} // main 


SSL_CTX* InitCTX(void) { 


    SSL_METHOD const *method; 
    SSL_CTX *ctx; 


    // Load cryptos, et.al. 
    OpenSSL_add_all_algorithms(); 


    // Bring in and register error messages 
    SSL_load_error_strings(); 


    // Create new client-method instance 
    method = SSLv3_client_method(); 


    // Create new context 
    ctx = SSL_CTX_new(method); 


    if (ctx == NULL) { 


     ERR_print_errors_fp(stderr); 
     abort(); 


    } // if 


    return ctx; 


} //InitCTX 


int OpenConnection(const char *hostname, int port) { 


    int sd; 
    struct hostent *host; 
    struct sockaddr_in addr; 


    if ((host = gethostbyname(hostname)) == NULL) { 


     perror(hostname); 
     abort(); 


    } // if 


    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(); 


    } // if 


    return sd; 


} // OpenConnection 


void ShowCerts(SSL* ssl) { 


    X509 *cert; 
    char *line; 


    cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */ 


    if (cert != NULL) { 


     printf("\nServer certificate:\n"); 
     line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); 
     printf("Subject: %s\n", line); 


     // Free the malloc'ed string 
     free(line); 
     line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); 
     printf("Issuer: %s\n", line); 


     // Free the malloc'ed string 
     free(line); 


     // Free the malloc'ed certificate copy 
     X509_free(cert); 


    } // if 


    else printf("No certificates.\n"); 


} // ShowCerts 

回答

2

你是對的。連接是安全的(從竊聽),具有完整性(防止注入,截斷和修改)和身份驗證(同行是他說他在證書中的人),所有這些都是由交通工具自動爲您完成的,但它仍然缺乏授權(這是我想與之交談的人,以及此人在我的申請中的確切位置)。本質上,只有應用程序可以這樣做,所以取決於您的對等證書,獲得其SubjectDN,將其與某個本地用戶數據庫相關聯,檢查是否存在,檢查其角色等。

2

A 「安全連接」 可以看作是由兩件​​事情:

1認證:請務必連接到合作伙伴(此處:服務器),預計連接到

2加密:讓數據(由連接傳輸)再次受到保護

收到的證書從服務器可以用來完成1證書不一定參與2.

關於如何將服務器證書的驗證添加到您的客戶端T是在傳輸過程中閱讀,你可能喜歡看看這個SO回答:https://stackoverflow.com/a/12245023/694576(你可以在第一個地方完成......; - >)

有關TLS(SSL和前SSL 3.x的後繼者)的詳細信息,請參閱此處: http://en.wikipedia.org/wiki/Transport_Layer_Security

+0

它被視爲四件事:看我的答案。 – EJP

+0

感謝您的鏈接:)所以我會更好地實施TLS而不是SSL來確保在可預見的未來有一個很好的安全連接? – FiniteRed

+0

它只是名稱。 'TLS 1.0'與'SSL 3.1'相同。 'TLS'是'SSL'的繼承者。只要閱讀我鏈接的維基百科文章,你就會看到...... ;-) @FiniteRed – alk