首页 > 编程语言 >《安全编程技术》实验三 socket安全编程

《安全编程技术》实验三 socket安全编程

时间:2022-10-31 22:58:00浏览次数:93  
标签:addr AES encrypt socket len server 安全 编程技术 string

一、实验目的与要求:

(一)实验目的

该实验为设计性实验,实验目的如下:

  1. 了解本地计算机的网络配置。
  2. 熟悉面向对象编程/C编程环境,能够编写简单程序。
  3. 熟练网络查阅源代码资源并会调试,修改,测试。

(二)实验要求

  1. 本实验一人一组,编程语言为C/C++/C#/JAVA。
  2. 要求学生熟练掌握C/C++/C#/JAVA语言编程,多线程编程。
  3. 实验报告要求:
    • 实验报告要求包括实验目的、实验要求、实验内容(系统的设计和实现)、实验结果分析和实验体会等,重点在于实验内容(系统的设计和实现)和实验结果分析。实验报告要求上传和打印。
    • 写出系统设计和实现过程中的心得和体会,并回答实验中的思考题。
    • 实验报告撰写规范请见附。

 

二、实验内容、步骤及结论

(一)实验内容

  1. 实现简单的基于TCP或UDP的通信程序(控制台和视窗都可以),要求使用VC/JAVA/C#编程。
  2. 对完成的socket通信进行安全性设置,4项任选2项实现(1.做用户验证(用户未注册或者密码不正确,就断开连接)2.加密信息内容3.超时机制4.黑名单机制)。

(二)代码:https://segmentfault.com/a/1190000000736700

1.服务器端server.c

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "aes_options.h" //add

int main()
{
	int server_fd;
	int client_fd;
	int len;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int sin_size;
	char buffer[BUFSIZ];
	// printf("%d",BUFSIZ);
	memset(&server_addr, 0, sizeof(server_addr)); // initialize struct
	memset(&server_addr, 0, sizeof(client_addr));

	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = INADDR_ANY;
	server_addr.sin_port = htons(9000);

	if ((server_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) // create server socket
	{
		perror("socket create failed");
		return 1;
	}

	if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0) // bind info on server socket
	{
		perror("bind failed");
		return 1;
	}

	listen(server_fd, 5); // listen port 9000

	sin_size = sizeof(struct sockaddr_in);

	if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &sin_size)) < 0)
	{
		perror("accept failed");
		return 1;
	}

	printf("accept client %s\n", inet_ntoa(client_addr.sin_addr));
	len = send(client_fd, "Welcome to my server\n", 21, 0);

	while ((len = recv(client_fd, buffer, BUFSIZ, 0)) > 0)
	{

		char *decryto_string = NULL;		   // add
		decrypt(buffer, &decryto_string, len); // add
		printf("%s \n", decryto_string);
		if (send(client_fd, decryto_string, len, 0) < 0) // modified
		{
			perror("send failed");
			return 1;
		}
	}

	close(client_fd);
	close(server_fd);

	return 0;
}

2.客户端client.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "aes_options.h"           //add

int main()
{
    int len;
    int client_sockfd;  
    struct sockaddr_in server_addr;
    char buffer[BUFSIZ];
    char *encrypt_string = NULL;
    memset(&server_addr, 0, sizeof(server_addr));

    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(9000);

    if((client_sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("socket create failed");
        return 1;

    }
    int username;
    int password;
    printf("enter the username:");
    scanf("%d", &username);
    printf("enter the password:");
    scanf("%d", &password);
    if (username !=2020 || password != 1212)
    {
        printf("uncorrect name!\n");
        return 1;
    }
    
    

    if(connect(client_sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
    {
        perror("connect failed");
        return 1;
    }

    printf("connect to server\n");
    len = recv(client_sockfd, buffer, BUFSIZ, 0);

    buffer[len] = '\0';
    printf("%s", buffer);

    while(1)
    {
        printf("enter a data:");
        scanf("%s", buffer);
        if(!strcmp(buffer,"quit"))
            break;
        int encrypt_length = encrypt(buffer, &encrypt_string);     //add
        len = send(client_sockfd, encrypt_string, encrypt_length, 0); //add
        len = recv(client_sockfd, buffer, BUFSIZ, 0);
        buffer[len] = '\0';
        printf("recived:%s \n", buffer);
    }

    close(client_sockfd);
    printf("bye");


    return 0;
}

/*char username;
    int password;
    printf("enter the username:");
    scanf("%s", &username);
    printf("enter the password:");
    scanf("%d", &password);
    if (username != "ycy" || password != 20201212)
    {
        printf("uncorrect name!\n");
        return 1;
    }
    */

3.加密解密函数openssl.c

#include <stdio.h>
#include <openssl/aes.h>
#include <stdlib.h>
#include <string.h>

int encrypt(char *input_string, char **encrypt_string)
{
    AES_KEY aes;
    unsigned char key[AES_BLOCK_SIZE]; // AES_BLOCK_SIZE = 16
    unsigned char iv[AES_BLOCK_SIZE];  // init vector
    unsigned int len;                  // encrypt length (in multiple of AES_BLOCK_SIZE)
    unsigned int i;
    // set the encryption length
    len = 0;
    if ((strlen(input_string) + 1) % AES_BLOCK_SIZE == 0)
    {
        len = strlen(input_string) + 1;
    }
    else
    {
        len = ((strlen(input_string) + 1) / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE;
    }
    // Generate AES 128-bit key
    for (i = 0; i < 16; ++i)
    {
        key[i] = 32 + i;
    }
    // Set encryption key
    for (i = 0; i < AES_BLOCK_SIZE; ++i)
    {
        iv[i] = 0;
    }
    if (AES_set_encrypt_key(key, 128, &aes) < 0)
    {
        fprintf(stderr, "Unable to set encryption key in AES\n");
        exit(0);
    }
    // alloc encrypt_string
    *encrypt_string = (unsigned char *)calloc(len, sizeof(unsigned char));
    if (*encrypt_string == NULL)
    {
        fprintf(stderr, "Unable to allocate memory for encrypt_string\n");
        exit(-1);
    }
    // encrypt (iv will change)
    AES_cbc_encrypt(input_string, *encrypt_string, len, &aes, iv, AES_ENCRYPT);
    return len;
}
void decrypt(char *encrypt_string, char **decrypt_string, int len)
{
    unsigned char key[AES_BLOCK_SIZE]; // AES_BLOCK_SIZE = 16
    unsigned char iv[AES_BLOCK_SIZE];  // init vector
    AES_KEY aes;
    int i;
    // Generate AES 128-bit key
    for (i = 0; i < 16; ++i)
    {
        key[i] = 32 + i;
    }
    // alloc decrypt_string
    *decrypt_string = (unsigned char *)calloc(len, sizeof(unsigned char));
    if (*decrypt_string == NULL)
    {
        fprintf(stderr, "Unable to allocate memory for decrypt_string\n");
        exit(-1);
    }
    // Set decryption key
    for (i = 0; i < AES_BLOCK_SIZE; ++i)
    {
        iv[i] = 0;
    }
    if (AES_set_decrypt_key(key, 128, &aes) < 0)
    {
        fprintf(stderr, "Unable to set decryption key in AES\n");
        exit(-1);
    }
    // decrypt
    AES_cbc_encrypt(encrypt_string, *decrypt_string, len, &aes, iv,
                    AES_DECRYPT);
}

4.AES头文件aes_options.h

#ifndef _ASE_H_
#define _ASE_H_
	int encrypt(char *input_string, char **encrypt_string);
	void decrypt(char *encrypt_string, char **decrypt_string, int len);
#endif

(三)运行

gcc -I. openssl.c server.c -o server -lcrypto

gcc -I. openssl.c client.c -o client -lcrypto

先运行server,再运行client

输入quit退出

若用户名或密码错误,无法进入

 

三、实验体会

  微信、QQ、手机APP在进行网络连接时有何种安全措施?

  为了确保即时通讯的稳定性,采用了短链接(HTTP协议)和长链接(TCP协议)相结合的方式,分别应对状态协议和数据传输协议。短链接方式采用HTTP协议,主要用于用户登录信息验证、获取好友列表、用户头像、行为日志上报、刷新朋友圈等短期状态型的应用;长链接方式采用TCP协议,主要用于接收/发送文本消息、语音、图片、视频文件等传输过程需要保持连接状态的数据的传输。

  微信采用SYNC协议,是参考Activesync来实现的。SYNC是基于状态同步的协议,将信息的收发过程看作状态同步的过程。服务器每收到最新的消息或更新好友状态,都会将客户端与服务端消息进行同步。微信平台将交互模式简单化,只需要推送一个消息到达的通知,终端通过收到的通知进行信息同步。这种简化模式有利于微信在各种平台上的应用,通过状态差值同步数据的方式,获得最小的数据变更。同时,采用增量的传输模式得到最小的数据传输量。采用SYNC协议,可以确保信息是稳定传送、按序到达的。

标签:addr,AES,encrypt,socket,len,server,安全,编程技术,string
From: https://www.cnblogs.com/20201212ycy/p/16846180.html

相关文章

  • 拳头产品|海泰虎讯,新一代安全即时通讯系统
    即时通讯系统是目前互联网上最为流行的通信方式,各种各样的即时通讯软件也层出不穷。随着移动办公的快速普及,即时通讯软件在移动办公中得到越来越广泛的应用,已经成为日常办公......
  • 你怎么设计一个线程安全的Servlet?
    1.最直接的办法,就是用上面的SingleThreadModel接口既然单例会有共享实例变量导致线程不安全的问题,那就改成多例的呗。但是,这个接口都已经被官方废弃了,这就说明官方也不推荐......
  • JAVA面试官:请说说如何设计线程安全的单例模式?
    单例模式已经被讲烂了,这边复习一下双重检测锁下的线程安全的单例模式。(单例模式复习顶配)publicclassMySingleton{privatestaticvolatileMySingletonmySingleto......
  • 你能证明Servlet线程不安全吗?
    Servlet默认是线程不安全的!Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。  当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml......
  • 端口安全学习笔记
    端口安全记录一些端口渗透时的方法和思路免责声明本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关.大纲Tips......
  • 系统安全及应用
        账号安全基本设施:将非登陆用户的Shell设为/sbin/noiogin锁定长期不使用的账号删除无用的账号锁定账号密码 passwd  shadow将用户设置成无法登录 ......
  • 内网安全之:域密码抓取及票据传递
    内网安全之:域密码抓取及票据传递目录内网安全之:域密码抓取及票据传递1mimikatz抓取密码1.1HashCat解密hash值1.2防范Windows密码抓取2传递攻击2.1NTLMhash......
  • 内网安全之:黄金&白银票据传递域控制器权限维持
    内网安全之:黄金&白银票据传递域控制器权限维持目录内网安全之:黄金&白银票据传递域控制器权限维持1GoldenTicket1.1导出krbtgt的NTLMHash1.2获取基本信息1.3Kerbe......
  • 内网安全之:MS14-068 Kerberos 域用户提权漏洞
    内网安全之:MS14-068Kerberos域用户提权漏洞目录内网安全之:MS14-068Kerberos域用户提权漏洞0漏洞说明(MS14-068;CVE-2014-6324)1pyKEK工具包2MSF中ms14_068利用......
  • 2022信息安全专业保研经历
    9.28终于来了,推免到此结束,上交网安专硕,感觉还是比较满足的吧,找了一个还不错的导师,这两三个月的煎熬生活算是结束了,写个小帖子记录一下这段保研的经历。offer:上交网安专硕......