zoukankan      html  css  js  c++  java
  • 20165331 第五次实验报告

    20165331 第五次实验报告

    实验一

    首先下载并解压openssl安装包后,进入源代码目录,使用如下命令:

    ./configure
    make
    sudo make install
    

    安装,并通过相应命令查看帮助文档

    man openssl
    

    1

    之后编写一个小程序来进行测试:

    `#include <stdio.h>
    #include <openssl/evp.h>
    
    int main(){
        OpenSSL_add_all_algorithms();
        return 0;
    }
    

    通过gcc -o test_openssl test_openssl.c -L/usr/local/ssl/lib -lcrypto -ldl -lpthread命令编译,并通过命令echo $?测试,结果为0即为成功。
    2

    作业一:
    源代码:服务器端:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    #define BUFLEN 10
    
    int main(int argc, char **argv)
    {
        int sockfd, newfd;
        struct sockaddr_in s_addr, c_addr;
        char buf[BUFLEN];
        socklen_t len;
        unsigned int port, listnum;
        
        /*建立socket*/
        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
            perror("socket");
            exit(errno);
        }else
            printf("socket create success!
    ");
        /*设置服务器端口*/    
        if(argv[2])
            port = atoi(argv[2]);
        else
            port = 4567;
        /*设置侦听队列长度*/
        if(argv[3])
            listnum = atoi(argv[3]);
        else
            listnum = 3;
        /*设置服务器ip*/
        bzero(&s_addr, sizeof(s_addr));
        s_addr.sin_family = AF_INET;
        s_addr.sin_port = htons(port);
        if(argv[1])
            s_addr.sin_addr.s_addr = inet_addr(argv[1]);
        else
            s_addr.sin_addr.s_addr = INADDR_ANY;
        /*把地址和端口帮定到套接字上*/
        if((bind(sockfd, (struct sockaddr*) &s_addr,sizeof(struct sockaddr))) == -1){
            perror("bind");
            exit(errno);
        }else
            printf("bind success!
    ");
        /*侦听本地端口*/
        if(listen(sockfd,listnum) == -1){
            perror("listen");
            exit(errno);    
        }else
            printf("the server is listening!
    ");
        while(1){
            printf("*****************聊天开始***************
    ");
            len = sizeof(struct sockaddr);
            if((newfd = accept(sockfd,(struct sockaddr*) &c_addr, &len)) == -1){
                perror("accept");        
                exit(errno);
            }else
                printf("正在与您聊天的客户端是:%s: %d
    ",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));
            while(1){
            _retry:
                /******发送消息*******/
                bzero(buf,BUFLEN);
                printf("请输入发送给对方的消息:");
                /*fgets函数:从流中读取BUFLEN-1个字符*/
                fgets(buf,BUFLEN,stdin);
                /*打印发送的消息*/
                //fputs(buf,stdout);
                if(!strncasecmp(buf,"quit",4)){
                    printf("server 请求终止聊天!
    ");
                    break;
                }
                /*如果输入的字符串只有"
    ",即回车,那么请重新输入*/
                if(!strncmp(buf,"
    ",1)){
                    printf("输入的字符只有回车,这个是不正确的!!!
    ");
                    goto _retry;
                }    
                /*如果buf中含有'
    ',那么要用strlen(buf)-1,去掉'
    '*/            
                if(strchr(buf,'
    '))
                    len = send(newfd,buf,strlen(buf)-1,0);
                /*如果buf中没有'
    ',则用buf的真正长度strlen(buf)*/    
                else
                    len = send(newfd,buf,strlen(buf),0);
                if(len > 0)
                    printf("消息发送成功,本次共发送的字节数是:%d
    ",len);            
                else{
                    printf("消息发送失败!
    ");
                    break;            
                }
                /******接收消息*******/
                bzero(buf,BUFLEN);
                len = recv(newfd,buf,BUFLEN,0);
                if(len > 0)
                    printf("客户端发来的信息是:%s,共有字节数是: %d
    ",buf,len);
                else{
                    if(len < 0 )
                        printf("接受消息失败!
    ");
                    else
                        printf("客户端退出了,聊天终止!
    ");
                    break;        
                }
            }
            /*关闭聊天的套接字*/
            close(newfd);
            /*是否退出服务器*/
            printf("服务器是否退出程序:y->是;n->否? ");
            bzero(buf, BUFLEN);
            fgets(buf,BUFLEN, stdin);
            if(!strncasecmp(buf,"y",1)){
                printf("server 退出!
    ");
                break;
            }
        }
        /*关闭服务器的套接字*/
        close(sockfd);
        return 0;
    }
    

    客户端:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    #define BUFLEN 10
    
    int main(int argc, char **argv)
    {
        int sockfd;
        struct sockaddr_in s_addr;
        socklen_t len;
        unsigned int port;
        char buf[BUFLEN];    
        
        /*建立socket*/
        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
            perror("socket");
            exit(errno);
        }else
            printf("socket create success!
    ");
    
        /*设置服务器端口*/    
        if(argv[2])
            port = atoi(argv[2]);
        else
            port = 4567;
        /*设置服务器ip*/
        bzero(&s_addr, sizeof(s_addr));
        s_addr.sin_family = AF_INET;
        s_addr.sin_port = htons(port);
        if (inet_aton(argv[1], (struct in_addr *)&s_addr.sin_addr.s_addr) == 0) {
            perror(argv[1]);
            exit(errno);
        }
        /*开始连接服务器*/    
        if(connect(sockfd,(struct sockaddr*)&s_addr,sizeof(struct sockaddr)) == -1){
            perror("connect");
            exit(errno);
        }else
            printf("conncet success!
    ");
        
        while(1){
            /******接收消息*******/
            bzero(buf,BUFLEN);
            len = recv(sockfd,buf,BUFLEN,0);
            if(len > 0)
                printf("服务器发来的消息是:%s,共有字节数是: %d
    ",buf,len);
            else{
                if(len < 0 )
                    printf("接受消息失败!
    ");
                else
                    printf("服务器退出了,聊天终止!
    ");
                break;    
            }
        _retry:    
            /******发送消息*******/    
            bzero(buf,BUFLEN);
            printf("请输入发送给对方的消息:");
            /*fgets函数:从流中读取BUFLEN-1个字符*/
            fgets(buf,BUFLEN,stdin);
            /*打印发送的消息*/
            //fputs(buf,stdout);
            if(!strncasecmp(buf,"quit",4)){
                printf("client 请求终止聊天!
    ");
                break;
            }
            /*如果输入的字符串只有"
    ",即回车,那么请重新输入*/
            if(!strncmp(buf,"
    ",1)){
                printf("输入的字符只有回车,这个是不正确的!!!
    ");
                goto _retry;
            }
            /*如果buf中含有'
    ',那么要用strlen(buf)-1,去掉'
    '*/    
            if(strchr(buf,'
    '))
                len = send(sockfd,buf,strlen(buf)-1,0);
            /*如果buf中没有'
    ',则用buf的真正长度strlen(buf)*/    
            else
                len = send(sockfd,buf,strlen(buf),0);
            if(len > 0)
                printf("消息发送成功,本次共发送的字节数是:%d
    ",len);            
            else{
                printf("消息发送失败!
    ");
                break;            
            }
        }
        /*关闭连接*/
        close(sockfd);
    
        return 0;
    }
    

    实验结果
    3
    4

    实验二

    加密代码:服务器:

    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <openssl/ssl.h>
    #include <openssl/err.h>
     #include <openssl/evp.h>
    
    
    #define MAXBUF 1024
    
    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
    ");
    
        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
    ");
    
        if (listen(sockfd, lisnum) == -1) {
            perror("listen");
            exit(1);
        } else
            printf("begin listen
    ");
    
        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
    ",
                       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'
    ",
                     buf, errno, strerror(errno));
                goto finish;
            } else
                printf("消息'%s'发送成功,共发送了%d个字节!
    ",
                       buf, len);
    
            bzero(buf, MAXBUF + 1);
            /* 接收客户端的消息 */
            len = SSL_read(ssl, buf, MAXBUF);
            if (len > 0)
                printf("接收消息成功:'%s',共%d个字节的数据
    ",
                       buf, len);
            else
                printf
                    ("消息接收失败!错误代码是%d,错误信息是'%s'
    ",
                     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;
    }
    

    客户端:

    #include <stdio.h>  
    #include <string.h>  
    #include <errno.h>  
    #include <sys/socket.h>  
    #include <resolv.h>  
    #include <stdlib.h>  
    #include <netinet/in.h>  
    #include <arpa/inet.h>  
    #include <unistd.h>  
    #include <openssl/ssl.h>  
    #include <openssl/err.h>
     #include <openssl/evp.h>
      
      
    #define MAXBUF 1024  
      
    void ShowCerts(SSL * ssl)  
    {  
        X509 *cert;  
        char *line;  
      
        cert = SSL_get_peer_certificate(ssl);  
        if (cert != NULL) {  
            printf("数字证书信息:
    ");  
            line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);  
            printf("证书: %s
    ", line);  
            free(line);  
            line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);  
            printf("颁发者: %s
    ", line);  
            free(line);  
           X509_free(cert);  
        } else  
            printf("无证书信息!
    ");  
    }  
      
    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("参数格式错误!正确用法如下:
    		%s IP地址 端口
    	比如:	%s 127.0.0.1 80
    此程序用来从某个"  
                 "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
    ");  
      
        /* 初始化服务器端(对方)的地址和端口信息 */  
        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
    ");  
      
        /* 连接服务器 */  
        if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {  
            perror("Connect ");  
            exit(errno);  
        }  
        printf("server connected
    ");  
      
        /* 基于 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
    ", SSL_get_cipher(ssl));  
            ShowCerts(ssl);  
        }  
      
        /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */  
        bzero(buffer, MAXBUF + 1);  
        /* 接收服务器来的消息 */  
        len = SSL_read(ssl, buffer, MAXBUF);  
        if (len > 0)  
            printf("接收消息成功:'%s',共%d个字节的数据
    ",  
                   buffer, len);  
        else {  
            printf  
                ("消息接收失败!错误代码是%d,错误信息是'%s'
    ",  
                 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'
    ",  
                 buffer, errno, strerror(errno));  
        else  
            printf("消息'%s'发送成功,共发送了%d个字节!
    ",  
                   buffer, len);  
      
      finish:  
        /* 关闭连接 */  
        SSL_shutdown(ssl);  
        SSL_free(ssl);  
        close(sockfd);  
        SSL_CTX_free(ctx);  
        return 0;  
    }
    

    分别通过命令gcc -o server server.c -I /usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl -lpthreadgcc -o telent telent.c -I /usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl -lpthread编译。

  • 相关阅读:
    Java实现 LeetCode 833 字符串中的查找与替换(暴力模拟)
    Java实现 LeetCode 833 字符串中的查找与替换(暴力模拟)
    Java实现 LeetCode 833 字符串中的查找与替换(暴力模拟)
    Java实现 LeetCode 832 翻转图像(位运算)
    Java实现 LeetCode 832 翻转图像(位运算)
    Java实现 LeetCode 832 翻转图像(位运算)
    Java实现 LeetCode 831 隐藏个人信息(暴力)
    Java实现 LeetCode 831 隐藏个人信息(暴力)
    Java实现 LeetCode 831 隐藏个人信息(暴力)
    how to use automapper in c#, from cf~
  • 原文地址:https://www.cnblogs.com/violence/p/10129230.html
Copyright © 2011-2022 走看看