这里附上先前(三)中的实验,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, BUF_SIZE, 0); //recv char buffRecv[BUF_SIZE]={0}; recv(clientSocket,buffRecv,BUF_SIZE,0); cout<<"KA加密以后的TGT:"<<buffRecv<<endl; char buffRecv2[BUF_SIZE]={0}; recv(clientSocket,buffRecv2,BUF_SIZE,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, 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, BUF_SIZE, 0); //recv char buffRecv[BUF_SIZE]={0}; recv(clientSocket,buffRecv,BUF_SIZE,0); cout<<"接收到的加密以后的TGT:"<<buffRecv<<endl; char buffRecv2[BUF_SIZE]={0}; recv(clientSocket,buffRecv2,BUF_SIZE,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] = '