2019年3月24日 星期日

c++ 寫一個簡單的 https server

參考文章: https://wiki.openssl.org/index.php/Simple_TLS_Server
先安裝好 openssl 開發檔及準備自我認証的憑證
sudo apt-get install libssl–dev
openssl req -x509 -nodes -days 30 -newkey rsa:2048 -keyout mykey.pem -out mycert.pem
編輯 https  server 主程式:
// server.c
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
int main()

    SSL_library_init(); 
    SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
    SSL_CTX_set_ecdh_auto(ctx, 1);
    SSL_CTX_use_certificate_file(ctx, "mycert.pem", SSL_FILETYPE_PEM);
    SSL_CTX_use_PrivateKey_file(ctx,  "mykey.pem", SSL_FILETYPE_PEM);
    struct sockaddr_in addr;
    socklen_t len = sizeof(addr);
    int server = socket(AF_INET, SOCK_STREAM, 0);
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(5000);
    addr.sin_addr.s_addr = INADDR_ANY;
    int  ok = 1;
    setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &ok, sizeof(ok));
    bind(server, (struct sockaddr*)&addr, sizeof(addr));
    listen(server, 10);  
    while(1) {
        int client = accept(server, (struct sockaddr*)&addr, &len);
        printf("Accept client IP= %s : port=%d\n",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
        SSL * ssl = SSL_new(ctx);
        SSL_set_fd(ssl, client);
        SSL_accept(ssl);
        char buf[1024];
        int bytes = SSL_read(ssl, buf, sizeof(buf));
        if (bytes > 0) { buf[bytes]=0; printf("Client: %s", buf); }
        char msg[] = "<html><head><meta charset='UTF-8'></head><Body>歡迎光臨</Body></html >";
        buf[0]=0;
        sprintf(buf            ,"HTTP/1.0 200 OK\n");
        sprintf(buf+strlen(buf),"Server: Welcome\n");
        sprintf(buf+strlen(buf),"Content-Type: text/html\n");
        sprintf(buf+strlen(buf),"Content-Length: %11ld\n",strlen(msg));
        sprintf(buf+strlen(buf),"Connection: close\n\n");  
        sprintf(buf+strlen(buf),"%s",msg);
        SSL_write(ssl, buf, strlen(buf));
        SSL_free(ssl);
        close(client);  
    };
    close(server);
    SSL_CTX_free(ctx);
}
編譯並執行
g++ server.c -lssl -lcrypto  -o server &&  ./server
用瀏覽器瀏覽  https://127.0.0.1:5000 , 如有警告信息, 選取並信任該憑證

沒有留言: