2-1. 基於OpenSSL的傳輸子系統實現
一. 基本傳輸子系統程式設計
客戶端可上傳檔案至伺服器,或下載伺服器上的檔案
系統程式構架:
客戶端 | 伺服器 |
TCP建立連線 menu()-> 上傳命令、下載命令 close(socket) |
TCP建立連線 handle()-> 根據命令響應 close(socket); |
主函式框架:
客戶端 | 伺服器 |
int main(int argc, char *args[]) { if (argc != 2) { printf("usage: ./client 192.168.10.18 (serverip)\n"); 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,用於TCP通訊 /*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 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 }
|
按照客戶端的合適進行設定 //1.接收操作符--->>>第一部曲 --->>>1步 read(new_fd,&cmd,1); //讀取操作型別碼 //2.按照操作符進行命令函式 if(cmd == 'Q') { close(new_fd); break;} else handle(cmd); //3.進行正式檔案處理--->>>剩下4部曲
|
//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加密傳輸子系統程式設計完成,對應產生伺服器加密所需的公鑰與私鑰,分別進行編譯即可實現:對上傳、下載伺服器檔案的加密傳輸。
&n