WinSocket程式設計筆記(四)
阿新 • • 發佈:2020-04-15
這裡附上先前(三)中的實驗,AS與ALICE通訊時,ALICE客戶端的完整程式碼
#include <iostream> #include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") using namespace std; #define BUF_SIZE 100 const int PORT = 8000; int main() { WORD sockVersion = MAKEWORD(2,2); WSADATA data; if (WSAStartup(sockVersion,&data) != 0) { return 1; } SOCKET clientSocket = socket(AF_INET,SOCK_STREAM,0); if (clientSocket == INVALID_SOCKET){ cout << "Socket error" << endl;} SOCKADDR_IN ListenAddr; ListenAddr.sin_family=AF_INET; ListenAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");; ListenAddr.sin_port=htons(PORT); //connect int ret=0; ret=connect(clientSocket,(sockaddr*)&ListenAddr,sizeof(struct sockaddr_in)); //send char name[BUF_SIZE] = {"ALICE"}; send(clientSocket,name,BUF_SIZE,0); char secret[BUF_SIZE] = {"12345"}; send(clientSocket,secret,0); //recv char buffRecv[BUF_SIZE]={0}; recv(clientSocket,buffRecv,0); cout<<"KA加密以後的TGT:"<<buffRecv<<endl; char buffRecv2[BUF_SIZE]={0}; recv(clientSocket,buffRecv2,0); cout<<"KA加密以後的KSkey:"<<buffRecv2<<endl; //解密 int key=12345; //char轉string,buffRecv -> cipher string plain =""; string cipher=buffRecv; int offset = key % 26; for(int i = 0; i < cipher.length(); i++) { char c = cipher[i]; if(isalpha(c)) { if(c >= ‘a‘ && c <= ‘z‘) { c = ‘z‘ - ((‘z‘ - c + offset) % 26); plain += c; } else { c = ‘Z‘ - ((‘Z‘ - c + offset) % 26); plain += c; } } else if(isdigit(c)) { c = ‘9‘ - ((‘9‘ - c + offset) % 10); plain += c; } else { plain += c; } } cout<<"解密以後的TGT:"<<plain<<endl; string plain2 =""; string cipher2=buffRecv2; for(int i = 0; i < cipher2.length(); i++) { char c2 = cipher2[i]; if(isalpha(c2)) { if(c2 >= ‘a‘ && c2 <= ‘z‘) { c2 = ‘z‘ - ((‘z‘ - c2 + offset) % 26); plain2 += c2; } else { c2 = ‘Z‘ - ((‘Z‘ - c2 + offset) % 26); plain2 += c2; } } else if(isdigit(c2)) { c2 = ‘9‘ - ((‘9‘ - c2 + offset) % 10); plain2 += c2; } else { plain2 += c2; } } cout<<"解密以後的明文KSkey:"<<plain2<<endl; //不讓程式結束 while(1) { } //closesocket closesocket(clientSocket); return 0; }
上面的程式碼只能實現一次通訊,而且僅限於和AS通訊接收TGT和KS
關於如何實現Kerberos的完整通訊
因為Kerberos通訊時AS每次生成的隨機會話金鑰不同,所以我們不能多次通訊,必須要一次完成實驗。所以可行的方法有存入檔案,或者一次連線多個伺服器端。我選擇了後者,客戶端只要做到每次通訊完成以後斷開伺服器端就能一次性和三個伺服器端進行通訊。而伺服器端需要先開啟監聽埠,不然客戶端只會返回空內容。
修改以後能一次性和多個伺服器通訊的ALICE客戶端:
同時做到接收和傳送TGT和KS,接收和傳送Ticket和KAB,接收BOB伺服器端加密傳送的訊息:
#include <iostream> #include <stdio.h> #include <winsock2.h> #include<string.h> #pragma comment(lib,"ws2_32.lib") using namespace std; #define BUF_SIZE 100 const int PORT = 8000; const int PORT2 = 8002; const int PORT3 = 8001; int main() { //定義兩個全域性變數,之後會用來接收BOB主金鑰加密的ALICE和Kab char RECV[BUF_SIZE]={0}; char RECV2[BUF_SIZE]={0}; int KKAB=0; WORD sockVersion = MAKEWORD(2,0); cout<<"接收到的加密以後的TGT:"<<buffRecv<<endl; char buffRecv2[BUF_SIZE]={0}; recv(clientSocket,0); cout<<"接收到的加密以後的KSkey:"<<buffRecv2<<endl; //解密 int key=12345; //char轉string,buffRecv -> cipher string plain =""; string cipher=buffRecv; int offset = key % 26; for(int i = 0; i < cipher.length(); i++) { char c = cipher[i]; if(isalpha(c)) { if(c >= ‘a‘ && c <= ‘z‘) { c = ‘z‘ - ((‘z‘ - c + offset) % 26); plain += c; } else { c = ‘Z‘ - ((‘Z‘ - c + offset) % 26); plain += c; } } else if(isdigit(c)) { c = ‘9‘ - ((‘9‘ - c + offset) % 10); plain += c; } else { plain += c; } } cout<<"解密以後的TGT:"<<plain<<endl; string plain2 =""; string cipher2=buffRecv2; for(int i = 0; i < cipher2.length(); i++) { char c2 = cipher2[i]; if(isalpha(c2)) { if(c2 >= ‘a‘ && c2 <= ‘z‘) { c2 = ‘z‘ - ((‘z‘ - c2 + offset) % 26); plain2 += c2; } else { c2 = ‘Z‘ - ((‘Z‘ - c2 + offset) % 26); plain2 += c2; } } else if(isdigit(c2)) { c2 = ‘9‘ - ((‘9‘ - c2 + offset) % 10); plain2 += c2; } else { plain2 += c2; } } cout<<"解密以後的KSkey:"<<plain2<<endl; //KSkey從string轉char //string轉char,plain2 -> pp char pp[100]; int i0; for( i0=0;i0<plain2.length();i0++) { pp[i0] = plain2[i0]; } pp[i0] = ‘\0‘; //KSkey從char轉成int(不能從string直接轉int) int INTKSkey=0; INTKSkey=atoi(pp); cout<<"與AS通訊完畢!"<<endl; //closesocket closesocket(clientSocket); WSACleanup(); int U; cout<<"---------------------輸入數字1與TGS進行連線---------------------"<<endl; cout<<"請輸入數字:"<<endl; cin>>U; if(U==1){ //再開啟 WORD sockVersion = MAKEWORD(2,&data) != 0) { return 1; } SOCKET client2Socket = socket(AF_INET,0); if (client2Socket == INVALID_SOCKET){ cout << "Socket error" << endl;} SOCKADDR_IN ListenAddr2; ListenAddr2.sin_family=AF_INET; ListenAddr2.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");; ListenAddr2.sin_port=htons(PORT2); //connect TGS int ret2=0; ret2=connect(client2Socket,(sockaddr*)&ListenAddr2,sizeof(struct sockaddr_in)); //string轉char,明文TGT-> T char T[100]; int i; for( i=0;i<plain.length();i++) { T[i] = plain[i]; } T[i] = ‘\0‘; //string轉char,KSkey -> Y //send send(client2Socket,T,0); char sendd[BUF_SIZE] = {"BOB"}; send(client2Socket,sendd,0); send(client2Socket,pp,0); //recv char buffRecv3[BUF_SIZE]={0}; recv(client2Socket,buffRecv3,100,0); cout<<"BOB主金鑰加密以後的ALICE:"<<buffRecv3<<endl; //存入全域性變數,後面還要呼叫 memcpy(RECV,strlen(buffRecv3)); char buffRecv4[BUF_SIZE]={0}; recv(client2Socket,buffRecv4,0); cout<<"BOB主金鑰加密以後的Kab:"<<buffRecv4<<endl; //存入全域性變數,後面還要呼叫 memcpy(RECV2,strlen(buffRecv4)); char buffRecv5[BUF_SIZE]={0}; recv(client2Socket,buffRecv5,0); cout<<"KS加密以後的BOB:"<<buffRecv5<<endl; char buffRecv6[BUF_SIZE]={0}; recv(client2Socket,buffRecv6,0); cout<<"KS加密以後的Kab:"<<buffRecv6<<endl; //KS解密Kab string plain4 =""; string cipher4=buffRecv6; int offset4 = INTKSkey % 26; int i4; for( i4 = 0; i4 < cipher4.length(); i4++) { char c4 = cipher4[i4]; if(isalpha(c4)) { if(c4 >= ‘a‘ && c4 <= ‘z‘) { c4 = ‘z‘ - ((‘z‘ - c4 + offset4) % 26); plain4 += c4; } else { c4 = ‘Z‘ - ((‘Z‘ - c4 + offset4) % 26); plain4 += c4; } } else if(isdigit(c4)) { c4 = ‘9‘ - ((‘9‘ - c4 + offset4) % 10); plain4 += c4; } else { plain4 += c4; } } cout<<"解密以後的明文KAB:"<<plain4<<endl; //string轉int,並存入全域性變數 //先轉char //plain4轉char,plain4 -> p4 char p4[100]; int i5; for( i5=0;i5<plain4.length();i5++) { p4[i5] = plain4[i5]; } p4[i5] = ‘\0‘; //KAB從char轉成int(不能從string直接轉int) int INTKAB=0; INTKAB=atoi(p4); KKAB=INTKAB; //KS解密BOB string plain3 =""; string cipher3=buffRecv5; int offset3 = INTKSkey % 26; int i3; for( i3 = 0; i3 < cipher3.length(); i3++) { char c3 = cipher3[i3]; if(isalpha(c3)) { if(c3 >= ‘a‘ && c3 <= ‘z‘) { c3 = ‘z‘ - ((‘z‘ - c3 + offset3) % 26); plain3 += c3; } else { c3 = ‘Z‘ - ((‘Z‘ - c3 + offset3) % 26); plain3 += c3; } } else if(isdigit(c3)) { c3 = ‘9‘ - ((‘9‘ - c3 + offset3) % 10); plain3 += c3; } else { plain3 += c3; } } cout<<"解密以後的BOB:"<<plain3<<endl; if(plain3=="BOB") { cout<<"與TGS傳輸成功!"<<endl; } closesocket(client2Socket); WSACleanup(); } int U2; cout<<"---------------------輸入數字1與BOB進行連線---------------------"<<endl; cout<<"請輸入數字:"<<endl; cin>>U2; if(U2==1){ //再開啟 WORD sockVersion = MAKEWORD(2,&data) != 0) { return 1; } SOCKET client3Socket = socket(AF_INET,0); if (client3Socket == INVALID_SOCKET){ cout << "Socket error" << endl;} SOCKADDR_IN ListenAddr3; ListenAddr3.sin_family=AF_INET; ListenAddr3.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");; ListenAddr3.sin_port=htons(PORT3); //connect TGS int ret3=0; ret3=connect(client3Socket,(sockaddr*)&ListenAddr3,sizeof(struct sockaddr_in)); //send send(client3Socket,RECV,0); Sleep(1000); send(client3Socket,RECV2,0); //recv char buffRecv8[BUF_SIZE]={0}; recv(client3Socket,buffRecv8,0); cout<<"接收到的資訊:"<<buffRecv8<<endl; //KAB解密訊息 string plain8 =""; string cipher8=buffRecv8; int offset8 = KKAB % 26; for(int i8 = 0; i8 < cipher8.length(); i8++) { char c8 = cipher8[i8]; if(isalpha(c8)) { if(c8 >= ‘a‘ && c8 <= ‘z‘) { c8 = ‘z‘ - ((‘z‘ - c8 + offset8) % 26); plain8 += c8; } else { c8 = ‘Z‘ - ((‘Z‘ - c8 + offset8) % 26); plain8 += c8; } } else if(isdigit(c8)) { c8 = ‘9‘ - ((‘9‘ - c8 + offset8) % 10); plain8 += c8; } else { plain8 += c8; } } cout<<"接收成功!"<<endl; cout<<"解密以後的訊息:"<<plain8<<endl; closesocket(client3Socket); WSACleanup(); } //程式不退出 while(1) { } return 0; }
(待續)