码迷,mamicode.com
首页 > 其他好文 > 详细

2018-2019-1 20165209 20165215 实验五 通讯协议设计

时间:2018-12-15 00:55:58      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:开放源代码   保护   设计   sig   选项   资源   tcp通信   指定   libs   

2018-2019-1 20165209 20165215 实验五 通讯协议设计


实验内容

任务一

  1. 两人一组
  2. 基于Socket实现TCP通信,一人实现服务器,一人实现客户端
    研究OpenSSL算法,测试对称算法中的AES,非对称算法中的RSA,Hash算法中的MD5
  3. 选用合适的算法,基于混合密码系统实现对TCP通信进行机密性、完整性保护。
  4. 学有余力者,对系统进行安全性分析和改进。

任务二

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

技术分享图片

实验步骤

任务一

Linux下OpenSSL的安装与测试

  • 下载openssl-1.1.0j
  • 解压openssl-1.1.0j :tar xzvf openssl-1.1.0j.tar.gz
  • 进入源代码目录:cd openssl-1.1.0-pre1
  • 编译安装:
./config
$ make
$ make test
$ make install
  • 编写测试代码test_openssl.c
 #include <stdio.h>
      #include <openssl/evp.h>
      int main(){
         OpenSSL_add_all_algorithms();
         return 0;
      }
  • 编译生成可执行文件test_openssl:-o test_openssl test_openssl.c -L/usr/local/ssl/lib -lcrypto -ldl -lpthread

[注]:-L选项——指定链接库的文件夹地址;-lcrypto——导入OpenSSL所需包;-ldl选项——加载动态库;-lpthread选项——链接POSIX thread库

  • 执行./test_openssl;echo $?,结果正确显示0

技术分享图片

测试AES算法

  • 相关知识
    • 设置加密密钥:int AES_set_encrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key);
    • 设置解密密钥:int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
    • 对数据进行加解密:AES_ecb_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key, const int enc);
  • 测试结果如下:

技术分享图片

测试RSA算法

  • 相关知识
    • 生成一个密钥:openssl genrsa -out prikey.pem 1024,这个文件包含了公钥和密钥两部分,-out指定生成的文件名,后面的1024是生成密钥的长度
    • 分离出公钥:openssl rsa -in prikey.pem -pubout -out pubkey.pem,其中-in指定输入文件
    • 用公钥对文件加密:openssl rsautl -encrypt -pubin -inkey pubkey.pem -in a.text -out b.text
    • 用私钥解密:openssl rsautl -decrypt -inkey prikey.pem -in b.text
  • 测试结果如下:

技术分享图片

测试MD5算法

  • 相关知识:
    • 初始化MD5上下文结构:int MD5_Init(MD5_CTX *c);
    • 刷新MD5,将文件连续数据分片放入进行MD5刷新:int MD5_Update(MD5_CTX *c, const void *data, size_t len);
    • 产生最终的MD5数据:int MD5_Final(unsigned char *md, MD5_CTX *c);
    • 直接产生字符串的MD5:unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
  • 测试结果如下:

技术分享图片

实现TCP通信

技术分享图片

任务二

相关知识

  • OpenSSL函数介绍:OpenSSL是一个开放源代码的SSL协议的产品实现,它采用C语言作为开发语言,具备了跨系统的性能。调用OpenSSL的函数就可以实现一个SSL加密的安全数据传输通道,从而保护客户端和服务器之间数据的安全。
    • 头文件:
    #include <openssl/ssl.h>
    #include <openssl/err.h>
  • 基于OpenSSL的程序都要遵循以下几个步骤:
    • OpenSSL初始化::在使用OpenSSL之前,必须进行相应的协议初始化工作,可以通过int SSL_library_int(void);实现
    • 选择会话协议:在利用OpenSSL开始SSL会话之前,需要为客户端和服务器制定本次会话采用的协议,目前能够使用的协议包括TLSv1.0、SSLv2、SSLv3、SSLv2/v3。
    • 创建会话环境:在OpenSSL中创建的SSL会话环境称为CTX,使用不同的协议会话,其环境也不一样的。
      • 申请SSL会话环境的OpenSSL函数是:SSL_CTX *SSL_CTX_new(SSL_METHOD * method);
      • 制定证书验证方式的函数是:int SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int(*verify_callback),int(X509_STORE_CTX *));
      • 为SSL会话环境加载CA证书的函数是:SSL_CTX_load_verify_location(SSL_CTX *ctx,const char *Cafile,const char *Capath);
      • 为SSL会话加载用户证书的函数是:SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file,int type);
      • 为SSL会话加载用户私钥的函数是:SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx,const char* file,int type);
      • 在将证书和私钥加载到SSL会话环境之后,就可以调用int SSL_CTX_check_private_key(SSL_CTX *ctx);来验证私钥和证书是否相符:
    • 建立SSL套接字
      • SSL套接字是建立在普通的TCP套接字基础之上,在建立SSL套接字时可以使用下面的一些函数:
      SSL *SSl_new(SSL_CTX *ctx);//申请一个SSL套接字
      
      int SSL_set_fd(SSL *ssl,int fd);)//绑定读写套接字
      
      int SSL_set_rfd(SSL *ssl,int fd);//绑定只读套接字
      
      int SSL_set_wfd(SSL *ssl,int fd);//绑定只写套接字
    • 完成SSL握手
      • 在成功创建SSL套接字后,客户端应使用函数SSL_connect( )来完成握手过程:int SSL_connect(SSL *ssl);
      • 对服务器来讲,使用函数SSL_ accept ( )来完成握手过程:int SSL_accept(SSL *ssl);
      • 握手过程完成之后,通常需要询问通信双方的证书信息,以便进行相应的验证,这可以借助于X509 *SSL_get_peer_certificate(SSL *ssl);来实现
      • 使用X509_NAME *X509_get_subject_name(X509 *a);得到证书所用者的名字
    • 进行数据传输

      • 当SSL握手完成之后,就可以进行安全的数据传输了,在数据传输阶段,需要使用SSL_read( )和SSL_write( )来替代传统的read( )和write( )函数,来完成对套接字的读写操作:
      int SSL_read(SSL *ssl,void *buf,int num);
      int SSL_write(SSL *ssl,const void *buf,int num);
    • 结束SSL通信

      • 当客户端和服务器之间的数据通信完成之后,调用下面的函数来释放已经申请的SSL资源:
      int SSL_shutdown(SSL *ssl);//关闭SSL套接字
      void SSl_free(SSL *ssl);//释放SSL套接字
      void SSL_CTX_free(SSL_CTX *ctx); //释放SSL会话环境

运行

  • 编译方式:
gcc -o server server.c -I /usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl -lpthread

gcc -o telent telent.c -I /usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl -lpthread
  • 生产私钥和证书
openssl genrsa -out privkey.pem 1024

openssl req -new -x509 -key privkey.pem -out CAcert.pem -days 1095
  • 程序运行方式:
./server 1509 1 CAcert.pem privkey.pem
./telent 127.0.0.1 1509
  • 截图

技术分享图片

遇到的问题及解决方法

  • 问题一:执行./test_openssl;echo $?,结果显示错误

技术分享图片

  • 解决方法:在/usr/local/ssl路径下创建lib文件夹,然后把openssl_1.1.0j目录下所有*.a文件复制到/usr/local/ssl/lib路径下

技术分享图片

  • 问题二:无法生成RSA密钥

技术分享图片

  • 解决方法:输入命令sudo ln -s /usr/local/lib/libssl.so.1.1 /usr/lib/libssl.so.1.1sudo ln -s /usr/local/lib/libcrypto.so.1.1 /usr/lib/libcrypto.so.1.1后即可生成

技术分享图片

2018-2019-1 20165209 20165215 实验五 通讯协议设计

标签:开放源代码   保护   设计   sig   选项   资源   tcp通信   指定   libs   

原文地址:https://www.cnblogs.com/fyss/p/10122268.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!