# 2017-2018-1 《信息安全系统设计基础》实验五 通信协议设计

2017-2018-1 《信息安全系统设计基础》实验五 通信协议设计

通讯协议设计-1

在Ubuntu中完成 http://www.cnblogs.com/rocedu/p/5087623.html 中的作业

提交运行结果截图

  • openssl介绍:

OpenSSL是为网络通信提供安全及数据完整性的一种安全协议,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。

OpenSSL是一个强大的安全套接字层密码库,Apache使用它加密HTTPS,OpenSSH使用它加密SSH,但是,你不应该只将其作为一个库来使用,它还是一个多用途的、跨平台的密码工具。

OpenSSL整个软件包大概可以分成三个主要的功能部分:

  1. 密码算法库
  2. SSL协议库
  3. 应用程序
    OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。

作为一个基于密码学的安全开发包,OpenSSL提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。

openssl有众多子命令,分为三类:

  1. 标准命令
  2. 消息摘要(dgst子命令)
  3. 加密命令(enc子命令)

先生成自己的私有密钥文件,比如叫server.key:

openssl genrsa -des3 -out server.key 1024

genras表示生成RSA私有密钥文件,-des3表示用DES3加密该文件,1024是我们的key的长度。基于现在的计算机速度而言,一般用512就可以了,784可用于商业行为,1024可以用于军事用途了。生成server.key的时候会要求输入密码,这个密钥用来保护server.key文件,这样即使server.key文件被窃取,也打不开,拿不到私钥。

openssl rsa -noout -text -in server.key

如果你觉得server.key的保护密码太麻烦想去掉的话:

openssl rsa -in server.key -out server.key.unsecure(不过不推荐这么做)

下一步要得到证书了。得到证书之前我们要生成一个Certificate Signing Request。CA只对CSR进行处理。

openssl req -new -key server.key -out server.csr

生成CSR的时候屏幕上将有提示,依照其指示一步一步输入要求的信息即可。生成的csr文件交给CA签名后形成服务端自己的证书。

  • 过程

    • OpenSSL的安装

      1. 首先解压源代码:

      tar xzvf openssl-1.1.0-pre1.tar.gz

      1. 然后进入源代码目录:

      cd openssl-1.1.0-pre1

      1. 然后使用下列命令编译安装:
      ./configure
      
       make
       
       sudo make install
      
      • make时出现问题,不能解压.a文件,百度后也没有解决,因此后续程序部分是借用结对对象的电脑完成的。
    • 安装截图

    • 测试代码

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

    gcc -o to test_openssl.c -I /usr/local/ssl/inlcude /usr/local/ssl/lib -ldl -lpthread
    编译

    执行./to;echo $?,结果打印0

  • AES

使用的标准命令为 enc
openssl enc -ciphername [-in filename] [-out filename] [-pass arg] [-e] [-d] [-a/-base64]
   [-A] [-k password] [-kfile filename] [-K key] [-iv IV] [-S salt] [-salt] [-nosalt] [-z] [-md]
   [-p] [-P] [-bufsize number] [-nopad] [-debug] [-none] [-engine id]

-in filename:指定要加密的文件存放路径

-out filename:指定加密后的文件存放路径

-salt:自动插入一个随机数作为文件内容加密,默认选项

-e:可以指明一种加密算法,若不指的话将使用默认加密算法

-d:解密,解密时也可以指定算法,若不指定则使用默认算法,但一定要与加密时的算法一致

-a/-base64:使用-base64位编码格式
  • RSA
openssl rsa [-inform PEM|NET|DER] [-outform PEM|NET|DER] [-in filename] [-passin arg] [-out filename] [-passout arg]
   [-sgckey] [-des] [-des3] [-idea] [-text] [-noout] [-modulus] [-check] [-pubin] [-pubout] [-engine id]
常用选项:

-in filename:指明私钥文件

-out filename:指明将提取出的公钥保存至指定文件中 

-pubout:根据私钥提取出公钥
  • MD5
openssl passwd -1 -in test.txt -salt 12345678    

生成密码需要使用的标准命令为 passwd ,用法如下:

openssl passwd [-crypt] [-1] [-apr1] [-salt string] [-in file] [-stdin] [-noverify] [-quiet] [-table] {password}
常用选项有:

-1:使用md5加密算法

-salt string:加入随机数,最多8位随机数

-in file:对输入的文件内容进行加密

-stdion:对标准输入的内容进行加密
  • 作业
两人一组
基于Socket实现TCP通信,一人实现服务器,一人实现客户端
研究OpenSSL算法,测试对称算法中的AES,非对称算法中的RSA,Hash算法中的MD5
选用合适的算法,基于混合密码系统实现对TCP通信进行机密性、完整性保护。
学有余力者,对系统进行安全性分析和改进。

通讯协议设计-2

在Ubuntu中实现对实验二中的“wc服务器”通过混合密码系统进行防护
提交测试截图

  • 实验二
客户端:
#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>

#define MYPORT 155212

int main(int argc, char **argv)
{
    int sockfd, new_fd;
    socklen_t len;
    struct sockaddr_in my_addr, their_addr;
    char buffer[BUFSIZ];
    SSL_CTX *ctx;
    
    SSL_library_init();
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    ctx = SSL_CTX_new(SSLv23_server_method());
    if (ctx == NULL)
    {
        ERR_print_errors_fp(stdout);
        exit(1);
    }
    if (SSL_CTX_use_certificate_file(ctx, "cacert.pem", SSL_FILETYPE_PEM) <= 0)
    {
        ERR_print_errors_fp(stdout);
        exit(1);
    }
    if (SSL_CTX_use_PrivateKey_file(ctx, "privkey.pem", 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);
    }
    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, 5) == -1)
    {
        perror("listen");
        exit(1);
    }

    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("accept client %s
", inet_ntoa(their_addr.sin_addr));

        ssl = SSL_new(ctx);
        SSL_set_fd(ssl, new_fd);
        if (SSL_accept(ssl) == -1)
        {
            perror("accept");
            close(new_fd);
            break;
        }

        int length, i;
        long wordscount=0;
        int flag=1;

        while(1){
            bzero(buffer, BUFSIZ);
            if((length=SSL_read(ssl, buffer, BUFSIZ))>0){
                for(i=0; i<len; i++){
                    if(flag==0){
                        switch(buffer[i]){
                            case ' ':
                                wordscount++;
                                break;
                            case '
':
                                wordscount++;
                                break;
                            case '
':
                                wordscount++;
                                break;
                            default:
                                break;
                        }
                    }
                    if(buffer[i]== ' ' || buffer[i]=='
' || buffer[i]=='
') flag=1;
                    else flag=0;
                }
            }
            if(length<1024) break;
        }

        len = SSL_write(ssl, &wordscount, sizeof(long));

        SSL_shutdown(ssl);
        SSL_free(ssl);
        close(new_fd);
    }
    close(sockfd);
    SSL_CTX_free(ctx);
    return 0;
}
服务器:
#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>

#define MYPORT 155212

int main(int argc, char **argv)
{
    int sockfd, new_fd;
    socklen_t len;
    struct sockaddr_in my_addr, their_addr;
    char buffer[BUFSIZ];
    SSL_CTX *ctx;
    
    SSL_library_init();
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    ctx = SSL_CTX_new(SSLv23_server_method());
    if (ctx == NULL)
    {
        ERR_print_errors_fp(stdout);
        exit(1);
    }
    if (SSL_CTX_use_certificate_file(ctx, "cacert.pem", SSL_FILETYPE_PEM) <= 0)
    {
        ERR_print_errors_fp(stdout);
        exit(1);
    }
    if (SSL_CTX_use_PrivateKey_file(ctx, "privkey.pem", 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);
    }
    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, 5) == -1)
    {
        perror("listen");
        exit(1);
    }

    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("accept client %s
", inet_ntoa(their_addr.sin_addr));

        ssl = SSL_new(ctx);
        SSL_set_fd(ssl, new_fd);
        if (SSL_accept(ssl) == -1)
        {
            perror("accept");
            close(new_fd);
            break;
        }

        int length, i;
        long wordscount=0;
        int flag=1;

        while(1){
            bzero(buffer, BUFSIZ);
            if((length=SSL_read(ssl, buffer, BUFSIZ))>0){
                for(i=0; i<len; i++){
                    if(flag==0){
                        switch(buffer[i]){
                            case ' ':
                                wordscount++;
                                break;
                            case '
':
                                wordscount++;
                                break;
                            case '
':
                                wordscount++;
                                break;
                            default:
                                break;
                        }
                    }
                    if(buffer[i]== ' ' || buffer[i]=='
' || buffer[i]=='
') flag=1;
                    else flag=0;
                }
            }
            if(length<1024) break;
        }

        len = SSL_write(ssl, &wordscount, sizeof(long));

        SSL_shutdown(ssl);
        SSL_free(ssl);
        close(new_fd);
    }
    close(sockfd);
    SSL_CTX_free(ctx);
    return 0;
}

通讯协议设计-3

1 运行实验箱中,ARM调用Z32算法的实验,提交实验截图
2 用Z32的国密算法重新改写“wc服务器”的混合密码系统防护,提交运行截图

  • 不必完成
原文地址:https://www.cnblogs.com/nxy970408/p/8053897.html