linux下使用openssl对socket通信加密



普通socket编程

TCP服务器端

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
 int server_sockfd;//服务器端套接字
 int client_sockfd;//客户端套接字
 int len;
 struct sockaddr_in my_addr; //服务器网络地址结构体
 struct sockaddr_in remote_addr; //客户端网络地址结构体
 int sin_size;
 char buf[BUFSIZ]; //数据传送的缓冲区
 memset(&my_addr,0,sizeof(my_addr)); //数据初始化--清零
 my_addr.sin_family=AF_INET; //设置为IP通信
my_addr.sin_addr.s_addr=INADDR_ANY;//服务器IP地址--允许连接到所有本地地址上
 my_addr.sin_port=htons(8000); //服务器端口号


if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
{
perror("socket");
 return 1;
}


 if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)
{
perror("bind");
 return 1;
}


listen(server_sockfd,5);

 sin_size=sizeof(struct sockaddr_in);


 if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0)
{
perror("accept");
 return 1;
}
 printf("accept client %s/n",inet_ntoa(remote_addr.sin_addr));
 len=send(client_sockfd,"Welcome to my server/n",21,0);//发送欢迎信息


while((len=recv(client_sockfd,buf,BUFSIZ,0))>0))
{
buf[len]='/0';
printf("%s/n",buf);
if(send(client_sockfd,buf,len,0)<0)
{
perror("write");
 return 1;
}
}
close(client_sockfd);
close(server_sockfd);
 return 0;
}

TCP客户端编程(socket_comunication_client.c)

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
 int client_sockfd;
 int len;
 struct sockaddr_in remote_addr; //服务器端网络地址结构体
 char buf[BUFSIZ]; //数据传送的缓冲区
 memset(&remote_addr,0,sizeof(remote_addr)); //数据初始化--清零
 remote_addr.sin_family=AF_INET; //设置为IP通信
remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服务器IP地址
 remote_addr.sin_port=htons(8000); //服务器端口号


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


 if(connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0)
{
perror("connect");
 return 1;
}
 printf("connected to server/n");
len=recv(client_sockfd,buf,BUFSIZ,0);//接收服务器端信息
buf[len]='/0';
 printf("%s",buf); //打印服务器端信息


while(1)
{
 printf("Enter string to send:");
scanf("%s",buf);
if(!strcmp(buf,"quit")
break;
len=send(client_sockfd,buf,strlen(buf),0);
len=recv(client_sockfd,buf,BUFSIZ,0);
buf[len]='/0';
printf("received:%s/n",buf);
}
close(client_sockfd);//关闭套接字
 return 0;
}

以上代码转载自linux socket编程

Openssl AES加密

  1. 首先安装openssl和相关库(Ubuntu) apt-get install openssl libssl-dev
  2. 编写相关加密解密代码
  • 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
  • aes_options.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 AESn");
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_stringn");
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_stringn");
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 AESn");
exit(-1);
}

 // decrypt
 AES_cbc_encrypt(encrypt_string, *decrypt_string, len, &aes, iv, 
AES_DECRYPT);
}

修改普通socket的代码

在修改地方加上了//add或者modified注释 服务器端

#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 %sn", inet_ntoa(client_addr.sin_addr));
 len = send(client_fd,"Welcome to my servern", 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;
}

客户端

#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 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;

}


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

 printf("connect to servern");
 len = recv(client_sockfd, buffer, BUFSIZ, 0);

 buffer[len] = '';
 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] = '';
 printf("recived:%s n", buffer);
}

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


 return 0;
}

解释说明

  1. 文件aes_options.haes_options.c里面为两个函数,第一个为加密,第二个为解密.
  2. 在socket的两个文件中引入aes_options.h即可使用两个函数..
  3. 编译的时候需要执行如下命令:
gcc aes_options.c socket_comunication_server.c -o server -lcrypto
gcc aes_options.c socket_comunication_client.c -o client -lcrypto
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值