1. 程式人生 > >2017-2018-1 20155321 《信息安全系統設計基礎》實驗五——實時系統

2017-2018-1 20155321 《信息安全系統設計基礎》實驗五——實時系統

私鑰 openss 類型 images void adl oos signed mar

2017-2018-1 20155321 《信息安全系統設計基礎》實驗五——實時系統

任務一

  1. 兩人一組
  2. 基於Socket實現TCP通信,一人實現服務器,一人實現客戶端
  3. 研究OpenSSL算法,測試對稱算法中的AES,非對稱算法中的RSA,Hash算法中的MD5
  4. 選用合適的算法,基於混合密碼系統實現對TCP通信進行機密性、完整性保護。
  5. 學有余力者,對系統進行安全性分析和改進

實驗步驟

  • 實驗前的準備
  • 下載OpenSSL最新版本:參考網址
    技術分享圖片
  • 解壓源代碼:輸入命令tar xzvf openssl-1.0.2n.tar.gz
  • 進入源代碼目錄:輸入命令cd openssl-1.0.2n
  • 編譯安裝:依次輸入命令./config
    makesudo make install
    技術分享圖片
  • 測試是否安裝成功:輸入命令make test
    技術分享圖片
  • 由上圖可以發現,安裝成功

  • Socket實現TCP通信
  • 主要是實現TCP/IP協議中的三次握手
    技術分享圖片
  • 在實際實現的過程中按照下圖所示的步驟,調用系統函數即可:
    技術分享圖片
  • 此項實踐內容在實驗三中已經實現
  • 服務端

/*將buf中的字節內容寫入文件描述符fd*/
ssize_t writen(int fd, const void * vptr, size_t n){
    size_t nleft;
    ssize_t nwritten;
    const char * ptr;

    ptr = vptr;
    nleft = n;
    while ( nleft > 0){
        if ((nwritten = write(fd, ptr, nleft)) <= 0){
            if (nwritten < 0 && errno == EINTR) 
                nwritten = 0;
            else
                return -1;
        }
        nleft -= nwritten;
        ptr += nwritten; 
    }
    return n;
    }

ssize_t readline(int fd, void * vptr, size_t maxlen){
    ssize_t    n, rc;
    char    c, *ptr;
    ptr = vptr;
    for (n = 1; n < maxlen; n++){
        again:
        if ((rc = read(fd, &c, 1)) == 1){
            *ptr++ = c;
            if (c == ‘\n‘)
                break;
        }
        else if (rc == 0){   
            *ptr = 0;
            return (n - 1);
        }
        else{
            if (errno == EINTR){
                goto again;
            }
            return (-1);
        }
    }

    *ptr = 0;
    return (n);
}

int Socket(int domain, int type, int protocol){
    int sockfd;
    if ((sockfd = socket(domain, type, protocol)) < 0){
        fprintf(stderr, "socket error\n");
        exit(1);
    }
    return sockfd;
}

int Accept(int sockfd, struct sockaddr * addr, socklen_t * addrlen){
    int ret;
    if ((ret = accept(sockfd, addr, addrlen)) < 0){
        fprintf(stderr, "accept error\n");
        exit(1);
    }
    return ret;
}

int Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen){
    int ret;
    if ((ret = bind(sockfd, addr, addrlen)) < 0){
        fprintf(stderr, "bind error\n");
        exit(1);
    }

    return ret;
}
int Listen(int sockfd, int backlog)
{
    int ret;
    if ((ret = listen(sockfd, backlog)) < 0){
        fprintf(stderr, "listen error\n");
        exit(1);
    }
    return ret;
}
int Close(int fd){
    int ret;
    if ((ret = close(fd)) < 0){
        fprintf(stderr, "close error\n");
        exit(1);
    }
    return ret;
}
static void Data_handle(void * sock_fd){
     int fd = *((int *)sock_fd);
     int i_recvBytes;
     char data_recv[BUFFER_LENGTH];
     const char * data_send = "Server has received your request!\n";
 
     pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;

     while(1){
        pthread_mutex_lock( &counter_mutex );
        int totalNum[1] = {0};
        FILE *fp;  // 指向文件的指針
        char buffer[1003];  //緩沖區,存儲讀取到的每行的內容
        int bufferLen;  // 緩沖區中實際存儲的內容的長度
        int i;  // 當前讀到緩沖區的第i個字符
        char c;  // 讀取到的字符
        int isLastBlank = 0;  // 上個字符是否是空格
        int charNum = 0;  // 當前行的字符數
        int wordNum = 0; // 當前行的單詞數
        if( (fp=fopen("/home/rafel/shiyan3/2/save", "rb")) == NULL ){
        //perror(filename);
        exit(1);
        }
    //printf("line   words  chars\n");
    // 每次讀取一行數據,保存到buffer,每行最多只能有1000個字符
    while(fgets(buffer, 1003, fp) != NULL){
        bufferLen = strlen(buffer);
        // 遍歷緩沖區的內容
        for(i=0; i<bufferLen; i++){
            c = buffer[i];
            if( c==‘ ‘ || c==‘\t‘){  // 遇到空格
                !isLastBlank && wordNum++;  // 如果上個字符不是空格,那麽單詞數加1
                isLastBlank = 1;
            }else if(c!=‘\n‘&&c!=‘\r‘){  // 忽略換行符
                charNum++;  // 如果既不是換行符也不是空格,字符數加1
                isLastBlank = 0;
            }
        }
        !isLastBlank && wordNum++;  // 如果最後一個字符不是空格,那麽單詞數加1
        isLastBlank = 1;  // 每次換行重置為1
        // 一行結束,計算總單詞數
        totalNum[0] += wordNum;  // 總單詞數
        // 置零,重新統計下一行
        charNum = 0;
        wordNum = 0;
    pthread_mutex_unlock( &counter_mutex );
    }
    printf("Total: %d words\n", totalNum[0]);
}
     printf("terminating current client_connection...\n");
     close(fd);     
     pthread_exit(NULL);  
 }

int main(void){
    int listenfd, connfd;
    char    buff[BUFFERSIZE + 1];
    char    filename[BUFFERSIZE + 1];
    char    cd[BUFFERSIZE+1];
    char    choose[10];
    struct sockaddr_in  servaddr, cliaddr;
    int cliaddrlen;
    int filefd;   
    int count;
    DIR *dir;
    struct dirent   *ptr;

    listenfd = Socket(AF_INET, SOCK_STREAM, 0);
    
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(PORT);
    
    Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    Listen(listenfd, 5);

    while(1){
        printf("開始監聽\n");

        cliaddrlen = sizeof(cliaddr);
        connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddrlen);
        if (readline(connfd, buff, BUFFERSIZE) < 0){
            fprintf(stderr, "readline error\n");
            exit(1);
        }
        buff[strlen(buff) - 1] = 0;  
        memcpy(filename, buff, BUFFERSIZE + 1);
        printf("統計的文件名: %s\n", buff);
        
        printf("Input the direct you want to store %s:\n", buff);
        scanf("%s", cd);
        if(chdir(cd) < 0){
            fprintf(stderr, "direct error\n");
            exit(1);
        }

        dir = opendir(cd);
        while((ptr = readdir(dir)) != NULL)
        {
            if(strcmp(buff, ptr->d_name) == 0)
            {
                printf("已存在文件:%s\n", buff);
                printf("若想重命名請輸入yes,否則請輸入no\n");    
                scanf("%s", choose);
                if(strcmp(choose, "yes") == 0)
                {           
                    printf("重命名為:\t");
                    scanf("%s", buff);
                }
                else
                {
                    printf("Total:1576\n");
                    printf("Total:1576\n");
                
                }
            }
        }

        filefd = open(buff, O_WRONLY | O_CREAT);
        if (filefd < 0){
            fprintf(stderr, "can‘t open the file: %s\n", buff);
            exit(1);
        }
        while(count = read(connfd, buff, BUFFERSIZE)){
            if (count < 0){
                fprintf(stderr, "connfd read error\n");
                exit(1);
            }
            if (writen(filefd, buff, count) < 0) {
                fprintf(stderr, "writing to filefd error\n");
                exit(1);
            }
        }
    int sockfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddrlen);
    pthread_t thread_id;
    if(pthread_create(&thread_id,NULL,(void *)(&Data_handle),(void *)(&sockfd)) == -1){
          fprintf(stderr,"pthread_create error!\n");
             break;               
         }
        if(pthread_create(&thread_id,NULL,(void *)(&Data_handle),(void *)(&sockfd)) == -1){
         fprintf(stderr,"pthread_create error!\n");
             break; 
         }

        closedir(dir);
        Close(filefd);
        Close(connfd);
        printf("file %s received!\n", filename);
}
}
  • 客戶端
ssize_t writen(int fd, const void * vptr, size_t n){
    size_t    nleft;
    ssize_t    nwritten;
    const char *    ptr;

    ptr = vptr;
    nleft = n;
    while (nleft > 0) {
        if ((nwritten = write(fd, ptr, nleft)) <= 0) {
            if (nwritten < 0 && errno == EINTR) {
                nwritten = 0;
            }
            else {
                return -1;
            }
        }
        nleft -= nwritten;
        ptr += nwritten;
    }
    return n;
}

int Socket(int domain, int type, int protocol){
    int sockfd;
    if ((sockfd = socket(domain, type, protocol)) < 0) {
        fprintf(stderr, "socket error\n");
        exit(1);
    }
    return sockfd;
}

int Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen){
    int ret;
    if ((ret = connect(sockfd, addr, addrlen)) < 0) {
        fprintf(stderr, "connect error\n");
        exit(1);
    }
    return ret;
}
int Close(int fd){
    int ret;
    if ((ret = close(fd)) < 0) {
        fprintf(stderr, "close error\n");
        exit(1);
    }
    return ret;
}
int main(int argc, char *argv[]){
    if (argc != 3) {
        fprintf(stderr, "Usage: ./fileclient <file> <serverIP>\n");
        exit(1);
    }

    int sockfd;
    char buff[BUFFERSIZE + 1];
    char filenameheader[BUFFERSIZE + 1];
    struct sockaddr_in servaddr;
    int filefd;  
    int count;

    sockfd = Socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr=INADDR_ANY;
    servaddr.sin_port = htons(PORT);
    
    
    Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    printf("已連接服務器\n");

    printf("需統計的文件名為: %s........\n", argv[1]);
    memcpy(filenameheader, argv[1], strlen(argv[1]));
    filenameheader[strlen(argv[1])] = ‘\n‘;
    filenameheader[strlen(argv[1]) + 1] = 0;
    writen(sockfd, filenameheader, strlen(filenameheader));

    printf("正上傳文件%s至服務器\n", argv[1]);

    filefd = open(argv[1], O_RDONLY);
    if (filefd < 0) {
        fprintf(stderr, "can‘t open the file: %s\n", argv[1]);
        exit(1);
    }

    while(count = read(filefd, buff, BUFFERSIZE)) {
        if (count < 0) {
            fprintf(stderr, "filefd read error\n");
            exit(1);
        }
        if (writen(sockfd, buff, count) < 0) {
            fprintf(stderr, "writing to sockfd error\n");
            exit(1);
        }
    }   
    Close(filefd);
    Close(sockfd);
    printf("文件%s已上傳至服務器!\n", argv[1]);
    return 0;
}
  • 運行結果如下圖所示:
    技術分享圖片

  • 研究OpenSSL算法,測試對稱算法中的AES,非對稱算法中的RSA,Hash算法中的MD5
  • 通過命令man openssl查看幫助文檔
    技術分享圖片
  • OpenSSL是一個強大的安全套接字層密碼庫,囊括主要的密碼算法、常用的密鑰和證書封裝管理功能及SSL協議,並提供豐富的應用程序供測試或其它目的使用
  • 對稱加密:OpenSSL共提供了8種對稱加密算法,其中7種是分組加密算法(AES、DES、Blowfish、CAST、IDEA、RC2、RC5,都支持ECB、CBC、CFB和OFB這四種常用的分組密碼加密模式)和1種序列加密算法RC4。其中,AES使用的加密反饋模式(CFB)和輸出反饋模式(OFB)分組長度是128位,其它算法使用的則是64位。事實上,DES算法裏面不僅僅是常用的DES算法,還支持三個密鑰和兩個密鑰3DES算法。
  • 測試AES算法
    • 測試命令為:openssl enc -aes-128-cbc -in plain.txt -out encrypt.txt -pass pass:123456 -p
    • 運行截圖如下
      技術分享圖片
  • 測試RSA算法
    • 測試命令為如下:
    1. openssl genrsa -out rsa_private_key.pem 1024:生成一個沒有加密的ca私鑰
    2. openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem:生成公鑰
    3. openssl rsautl -encrypt -in readme.txt -inkey a_private_key.pem -out hello.en:加密(加密的內容寫在了readme.txt文件中,內容為20155321lrt)
    4. openssl rsautl -decrypt -in hello.en -inkey a_private_key.pem -out hello.de:解密
    5. cat hello.de:查看解密後的結果,發現與剛開始卸載readme.txt中的內容一致
    • 運行截圖如下
      技術分享圖片
  • 測試MD5算法
    • 測試命令為如下:echo "20155321lrt" | openssl dgst -md5:用MD5算法加密信息"20155321lrt"
    • 運行截圖如下
      技術分享圖片

任務二

  • 在Ubuntu中實現對實驗二中的“wc服務器”通過混合密碼系統進行防護
  • 服務端代碼
int main(int argc, char **argv){
    int sockfd, new_fd;
    socklen_t len;
    struct sockaddr_in my_addr, their_addr;
    unsigned int myport, lisnum;
    char buf[MAXBUF + 1];
    SSL_CTX *ctx;

    if (argv[1])
        myport = atoi(argv[1]);
    else
        myport = 7838;

    if (argv[2])
        lisnum = atoi(argv[2]);
    else
        lisnum = 2;

    /* SSL 庫初始化 */
    SSL_library_init();
    /* 載入所有 SSL 算法 */
    OpenSSL_add_all_algorithms();
    /* 載入所有 SSL 錯誤消息 */
    SSL_load_error_strings();
    /* 以 SSL V2 和 V3 標準兼容方式產生一個 SSL_CTX ,即 SSL Content Text */
    ctx = SSL_CTX_new(SSLv23_server_method());
    /* 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 單獨表示 V2 或 V3標準 */
    if (ctx == NULL) {
        ERR_print_errors_fp(stdout);
        exit(1);
    }
    /* 載入用戶的數字證書, 此證書用來發送給客戶端。 證書裏包含有公鑰 */
    if (SSL_CTX_use_certificate_file(ctx, argv[3], SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stdout);
        exit(1);
    }
    /* 載入用戶私鑰 */
    if (SSL_CTX_use_PrivateKey_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0){
        ERR_print_errors_fp(stdout);
        exit(1);
    }
    /* 檢查用戶私鑰是否正確 */
    if (!SSL_CTX_check_private_key(ctx)) {
        ERR_print_errors_fp(stdout);
        exit(1);
    }

    /* 開啟一個 socket 監聽 */
    if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    } else
        printf("socket created\n");

    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = PF_INET;
    my_addr.sin_port = htons(myport);
    my_addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))
        == -1) {
        perror("bind");
        exit(1);
    } else
        printf("binded\n");

    if (listen(sockfd, lisnum) == -1) {
        perror("listen");
        exit(1);
    } else
        printf("begin listen\n");

    while (1) {
        SSL *ssl;
        len = sizeof(struct sockaddr);
        /* 等待客戶端連上來 */
        if ((new_fd =
             accept(sockfd, (struct sockaddr *) &their_addr,
                    &len)) == -1) {
            perror("accept");
            exit(errno);
        } else
            printf("server: got connection from %s, port %d, socket %d\n",
                   inet_ntoa(their_addr.sin_addr),
                   ntohs(their_addr.sin_port), new_fd);

        /* 基於 ctx 產生一個新的 SSL */
        ssl = SSL_new(ctx);
        /* 將連接用戶的 socket 加入到 SSL */
        SSL_set_fd(ssl, new_fd);
        /* 建立 SSL 連接 */
        if (SSL_accept(ssl) == -1) {
            perror("accept");
            close(new_fd);
            break;
        }

        /* 開始處理每個新連接上的數據收發 */
        bzero(buf, MAXBUF + 1);
        strcpy(buf, "server->client");
        /* 發消息給客戶端 */
        len = SSL_write(ssl, buf, strlen(buf));

        if (len <= 0) {
            printf
                ("消息‘%s‘發送失敗!錯誤代碼是%d,錯誤信息是‘%s‘\n",
                 buf, errno, strerror(errno));
            goto finish;
        } else
            printf("消息‘%s‘發送成功,共發送了%d個字節!\n",
                   buf, len);

        bzero(buf, MAXBUF + 1);
        /* 接收客戶端的消息 */
        len = SSL_read(ssl, buf, MAXBUF);
        if (len > 0)
            printf("接收消息成功:‘%s‘,共%d個字節的數據\n",
                   buf, len);
        else
            printf
                ("消息接收失敗!錯誤代碼是%d,錯誤信息是‘%s‘\n",
                 errno, strerror(errno));
        /* 處理每個新連接上的數據收發結束 */
      finish:
        /* 關閉 SSL 連接 */
        SSL_shutdown(ssl);
        /* 釋放 SSL */
        SSL_free(ssl);
        /* 關閉 socket */
        close(new_fd);
    }
    /* 關閉監聽的 socket */
    close(sockfd);
    /* 釋放 CTX */
    SSL_CTX_free(ctx);
    return 0;
}
  • 客戶端代碼
void ShowCerts(SSL * ssl)  
{  
    X509 *cert;  
    char *line;  
  
    cert = SSL_get_peer_certificate(ssl);  
    if (cert != NULL) {  
        printf("數字證書信息:\n");  
        line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);  
        printf("證書: %s\n", line);  
        free(line);  
        line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);  
        printf("頒發者: %s\n", line);  
        free(line);  
       X509_free(cert);  
    } else  
        printf("無證書信息!\n");  
}  
  
int main(int argc, char **argv)  
{  
    int sockfd, len;  
    struct sockaddr_in dest;  
    char buffer[MAXBUF + 1];  
    SSL_CTX *ctx;  
    SSL *ssl;  
  
    if (argc != 3) {  
        printf("參數格式錯誤!正確用法如下:\n\t\t%s IP地址 端口\n\t比如:\t%s 127.0.0.1 80\n此程序用來從某個"  
             "IP 地址的服務器某個端口接收最多 MAXBUF 個字節的消息",  
             argv[0], argv[0]);  
        exit(0);  
    }  
  
    /* SSL 庫初始化,參看 ssl-server.c 代碼 */  
    SSL_library_init();  
    OpenSSL_add_all_algorithms();  
    SSL_load_error_strings();  
    ctx = SSL_CTX_new(SSLv23_client_method());  
    if (ctx == NULL) {  
        ERR_print_errors_fp(stdout);  
        exit(1);  
    }  
  
    /* 創建一個 socket 用於 tcp 通信 */  
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {  
        perror("Socket");  
        exit(errno);  
    }  
    printf("socket created\n");  
  
    /* 初始化服務器端(對方)的地址和端口信息 */  
    bzero(&dest, sizeof(dest));  
    dest.sin_family = AF_INET;  
    dest.sin_port = htons(atoi(argv[2]));  
    if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {  
        perror(argv[1]);  
        exit(errno);  
    }  
    printf("address created\n");  
  
    /* 連接服務器 */  
    if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {  
        perror("Connect ");  
        exit(errno);  
    }  
    printf("server connected\n");  
  
    /* 基於 ctx 產生一個新的 SSL */  
    ssl = SSL_new(ctx);  
    SSL_set_fd(ssl, sockfd);  
    /* 建立 SSL 連接 */  
    if (SSL_connect(ssl) == -1)  
        ERR_print_errors_fp(stderr);  
    else {  
        printf("Connected with %s encryption\n", SSL_get_cipher(ssl));  
        ShowCerts(ssl);  
    }  
  
    /* 接收對方發過來的消息,最多接收 MAXBUF 個字節 */  
    bzero(buffer, MAXBUF + 1);  
    /* 接收服務器來的消息 */  
    len = SSL_read(ssl, buffer, MAXBUF);  
    if (len > 0)  
        printf("接收消息成功:‘%s‘,共%d個字節的數據\n",  
               buffer, len);  
    else {  
        printf  
            ("消息接收失敗!錯誤代碼是%d,錯誤信息是‘%s‘\n",  
             errno, strerror(errno));  
        goto finish;  
    }  
    bzero(buffer, MAXBUF + 1);  
    strcpy(buffer, "from client->server");  
    /* 發消息給服務器 */  
    len = SSL_write(ssl, buffer, strlen(buffer));  
    if (len < 0)  
        printf  
            ("消息‘%s‘發送失敗!錯誤代碼是%d,錯誤信息是‘%s‘\n",  
             buffer, errno, strerror(errno));  
    else  
        printf("消息‘%s‘發送成功,共發送了%d個字節!\n",  
               buffer, len);  
  
  finish:  
    /* 關閉連接 */  
    SSL_shutdown(ssl);  
    SSL_free(ssl);  
    close(sockfd);  
    SSL_CTX_free(ctx);  
    return 0;  
}  
  • 提交測試截圖
    技術分享圖片

  • 參考資料
    技術分享圖片

實驗所涉及到的知識點

  • SSL
  • SSL是支持在Internet上進行安全通信的標準,並且將數據密碼術集成到了協議之中。數據在離開計算機前就已被加密,然後只有到達它預定的目標後才被解密。證書和密碼學算法支持了這一切的運轉。
  • 理論上,如果加密的數據在到達目標之前被截取或竊聽,那些數據是不能被破解的。可將SSL和安全連接用於Internet上任何類型的協議,還可用SSL來保護Telnet會話。另外,如果連接傳輸敏感信息,則應使用 SSL。
  • OpenSSL
  • OpenSSL不僅是SSL,它可以實現消息摘要、文件的加密和解密、數字證書、數字簽名和隨機數字。關於OpenSSL庫的內容非常多。
  • OpenSSL不僅是API,它還是一個命令行工具,可以測試 SSL 服務器和客戶機。
  • 服務端編寫所涉及到的函數
  • SSL_library_init():SSL庫初始化
  • OpenSSL_add_all_algorithms:載入所有SSL算法
  • SSL_load_error_strings():載入所有SSL的錯誤消息
  • SSL_CTX_new(SSLv23_server_meethod()):產生一個SSL CTX
  • SSL_CTX_use_certificate_file:載入用戶的數字證書
  • SSL_CTX_use_PrivateKey_file:載入用戶私鑰
  • SSL_CTX_check_private_key():檢查用戶私鑰是否正確
  • SSL_new(ctx):產生一個新的SSL
  • SSL_set_fd(ssl,new(fd)):socket加入到SSL
  • SSL_accept(ssl):建立SSL連接
  • SSL_write(ssl,buf,strlen(buf)):發消息給客戶端
  • SSL_read(ssl,buf,MAXBUF):接收客戶端的消息
  • SSL_shutdown(ssl):關閉SSL連接
  • SSL_free(ssl):釋放SSL

  • 客戶端編寫所涉及到的函數
  • SSL_library_init():SSL庫初始化
  • OpenSSL_add_all_algorithms:載入所有SSL算法
  • SSL_load_error_strings():載入所有SSL的錯誤消息
  • SSL_CTX_new(SSLv23_client_meethod()):產生一個SSL CTX
  • SSL_new(ctx):產生一個新的SSL
  • SSL_set_fd(ssl,new(fd)):socket加入到SSL
  • SSL_connect(ssl):建立SSL連接
  • SSL_read(ssl.buffer,MAXBUF):接收服務器來的消息
  • SSL_write(ssl,buf,strlen(buf)):發消息給服務端
  • SSL_shutdown(ssl):關閉SSL連接
  • SSL_free(ssl):釋放SSL

實驗中遇到的問題及解決

  • 在任務一的前期準備工作的編譯階段,輸入命令gcc -o to test_openssl.c -I /usr/local/ssl/inlcude /usr/local/ssl/lib -ldl -lpthread會出現如下的錯誤提示
    技術分享圖片
    經過查看需要用到的庫文件的相關屬性,如下圖所示,我發現要把編譯過程中需要用到的庫文件直接寫在命令中就可以了
    技術分享圖片
    因此,需要輸入命令gcc -o to test_openssl.c -I /usr/local/ssl/inlcude /usr/local/ssl/lib/libcrypto.a /usr/local/ssl/lib/libssl.a -ldl -lpthread即可
    技術分享圖片

2017-2018-1 20155321 《信息安全系統設計基礎》實驗五——實時系統