2-1. 基於OpenSSL的傳輸子系統實現

一. 基本傳輸子系統程序設計linux

  客戶端可上傳文件至服務器,或下載服務器上的文件算法

  系統程序構架:服務器

客戶端 服務器

TCP創建鏈接網絡

menu()-> 上傳命令、下載命令框架

close(socket)socket

TCP創建鏈接函數

handle()-> 根據命令響應工具

close(socket);優化

 

 

 

 

 

 

主函數框架:加密

客戶端 服務器
int main(int argc, char *args[])
{
    if (argc != 2)
    {
        printf("usage:./client 192.168.10.18(serverip)");
        exit(0);    //退出    
    }
    strcpy(ipaddr,args[1]); //將服務器地址放入字符串中 //1.創建鏈接  clink();  
    //2.輸入命令, 實現上傳和下載,實現菜單 menu(); //3.關閉鏈接
    close(sockfd); 
    return 0;
}
 
int clink()
{
    //1.建立socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);//IPv4
    
    /*2.1 初始化地址*/
    memset(&sockaddr1,0,sizeof(sockaddr1));//清零
    sockaddr1.sin_family = AF_INET;//協議族
    sockaddr1.sin_addr.s_addr = inet_addr(ipaddr);//
    sockaddr1.sin_port = htons(port);//端口,跟隨網絡傳輸,
    //2.鏈接服務器 connect(sockfd,(struct sockaddr *)&sockaddr1,
sizeof(sockaddr1)); return 1; }

 

int main()
{
    //1.1建立socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);  //IPv4,用於TCP通訊
    //1.2綁定地址
     /*初始化地址*/
    bzero(&server_addr,sizeof(struct sockaddr_in));//清零
    server_addr.sin_family = AF_INET;//協議族
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//跟隨網絡傳輸 
    server_addr.sin_port = htons(port);//端口,跟隨網絡傳輸
     /*綁定地址*/  
   //1.3監聽端口
bind(sockfd,(struct sockaddr *)(&server_addr),
                sizeof(struct sockaddr)); listen(sockfd,5); //客戶機數目 //1.4等待鏈接 while(1) { //client_addr保存客戶機地址 &sin_size長度的地址 new_fd = accept(sockfd,(struct sockaddr *)
                    (&client_addr),&sin_size);
//2.響應客戶端請求 while(1) { read(new_fd,&cmd,1); //讀取操做類型碼 if(cmd == 'Q') { close(new_fd); break; } else { handle(cmd); } } close(sockfd); } return 0; }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

---------------------------------------------------------------------------------------

  客戶端操做菜單及服務器端命令響應:

客戶端操做菜單 服務器端命令響應
 1 void menu()
 2 {
 3     while(1)
 4     {
 5         printf("\n-------- 1. Upload Files -----------\n");    
 6         printf("-------- 2. Download Files ----------\n");    
 7         printf("--------------- 3. Exit ------------\n");
 8         printf("Please input the Client command:");      
 9         command = getchar();    //等待用戶輸入字符
10         switch(command)
11         {
12 case '1': 13   {          //上傳文件
14     while ((c=getchar()) != '\n' && c != EOF);//獲鍵盤輸入文件名
15           fgets(file_u,30,stdin);  //stdin 標準輸入
16     upload_file(file_u);      //上傳
17   }
18 case '2': 19   {          //下載文件
20     while ((c=getchar()) != '\n' && c != EOF);
21           fgets(file_d,30,stdin);    //stdin 標準輸入    
22     download_file(file_d);    //下載
23   }
24 }

 

  
按照客戶端的合適進行設定
    //1.接收操做符--->>>第一部曲    --->>>1步
read(new_fd,&cmd,1);  //讀取操做類型碼
    //2.按照操做符進行命令函數
if(cmd == 'Q')
   { close(new_fd);     break;}
else
    handle(cmd);
    //3.進行正式文件處理--->>>剩下4部曲

void handle(char cmd) { switch(cmd) { case 'U'://服務器接收 { read(new_fd~ //接收文件名 --->>>2步 read(new_fd~ //接收文件長度 --->>>3步 fd = open(filename~//建立文件準備接受--->>>4步 write(fd,&buf~ //接收文件內容 --->>>5步 } case 'D'://服務器傳出 { read(new_fd~ //接收文件名 --->>>2步 fd = open(filename~//打開當前目錄文件--->>>3步 write(new_fd~ //發送文件長度 --->>>4步 write(new_fd //發送文件內容 --->>>5步 } case 'Q'://退出 { close(new_fd); break; } }

 

//case "1" 上傳文件 5部曲 void upload_file(char *filename)
{
    //1.打開要上傳的文件
fd = open(filename,O_RDONLY);  //以只讀方式打開文件
    //2.發送操做符 cmd="U"
write(sockfd,&cmd,1);
    //3.發送要上傳的文件名
write(sockfd,filename,size);
    //4.發送文件長度
stat(filename,&fstat);  //獲取文件屬性
write(sockfd,(void *)&(fstat.st_size),4);
    //5.發送文件
while((count=read(fd,(void *)buf,1024))>0)//讀取來的數據存到buf的空間
        write(sockfd,&buf,count);
}

//case "2"  下載文件   5部曲相同
void download_file(char *filename)
{
    //1.發送操做符 cmd="D"
write(sockfd,&cmd,1);
    //2.發送要下載的文件名
write(sockfd,filename,size);
    //3.建立接收文件
fd = open(filename,O_RDONLY|O_CREAT,0777);  //以只讀方式打開文件
    //4.接收文件長度
read(sockfd,&filesize,4);
    //5.接收文件
while((count=read(fd,(void *)buf,1024))>0)//讀取來的數據存到buf的空間
        write(fd,&buf,count);
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 -------------------------------------------------------------------------------------------------------------------

二. OpenSSL加密系統

  因爲網絡傳輸數據中,易被抓包軟件截獲。所以運用非對稱加密方法(公鑰、私鑰、數字證書)文件內容+公鑰 ->加密系統 ->私鑰,方可解密文件

a)公鑰與私鑰是配對時候用的;

b)私鑰加密的文件一樣用對應的公鑰解密,而爲了區分公鑰(防止公鑰被偷換,致使私密文件泄露),引入數字證書再加密

c)數字證書有權威機構發放,包含公鑰及持有人信息,沒法丟失假冒;

  SSL協議處於應用層協議(HTTP/SMTP)與TCP/IP協議之間,可實現文件加密傳輸。開源套接字層密碼庫OpenSSL,包含SSL、密碼算法、祕鑰證書管理功能等。 

  

 

 

 

 

 

-----------------------------------------------------------------------------------------------

  移植OpenSSL庫:

解壓安裝文件 -> 配置.config文件,修改交叉工具鏈arm-linux- -> 編譯make,make install,即生成OpenSSL的庫函數文件 .a、.so -> 置於/rootfs/lib/目錄下,OK!

  OpenSSL通信模型:基於下列通信模型優化原始傳輸子系統程序設計

客戶端SSL模型 服務器端SSL模型

初始化SSL ->

(建立套接字、鏈接服務器) ->

建立SSL ->

基於SSL收發數據 ->

關閉SSL ->

(關閉套接字)

初始化SSL ->

公鑰私鑰數字證書設置 ->

(建立套接字、綁定、等待鏈接) ->

建立SSL ->

基於SSL收發數據 ->

關閉SSL ->

(關閉套接字)

 

 

 

 

 

 

 

 

 

 

 

 

基於SSL收發數據:將write (sockfd,~) ->SSL_write (ssl,~)、read (sockfd,~) ->SSL_read (ssl,~)便可!

再對應產生公鑰、私鑰:(所有置於服務器目錄下)

  # openssl genrsa -out privkey.pem 2048  ->私鑰

  # openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 ->對應產生的公鑰

  OpenSSL加密傳輸子系統程序設計完成,對應產生服務器加密所需的公鑰與私鑰分別進行編譯便可實現:對上傳、下載服務器文件的加密傳輸。

相關文章
相關標籤/搜索