linuxC++使用server端使用openssl加密一个文件,并通过https发送到client,client使用openssl解密,写一个例子
时间: 2024-03-16 22:42:28 浏览: 10
以下是一个简单的示例,演示如何在Linux C++中使用OpenSSL加密文件并通过HTTPS发送到客户端,然后使用OpenSSL解密。
Server端加密文件并发送:
```cpp
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 443
#define CERTIFICATE "server.crt"
#define PRIVATE_KEY "server.key"
#define BUFFER_SIZE 1024
int main() {
// 初始化SSL库
SSL_library_init();
// 创建SSL上下文
SSL_CTX* ssl_ctx = SSL_CTX_new(TLSv1_2_server_method());
// 加载证书和私钥
SSL_CTX_use_certificate_file(ssl_ctx, CERTIFICATE, SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ssl_ctx, PRIVATE_KEY, SSL_FILETYPE_PEM);
// 创建socket
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
// 绑定端口
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(PORT);
if (bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
perror("bind");
exit(EXIT_FAILURE);
}
// 监听端口
if (listen(server_socket, 1) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
// 接受连接请求
struct sockaddr_in client_address;
socklen_t client_address_size = sizeof(client_address);
int client_socket = accept(server_socket, (struct sockaddr*)&client_address, &client_address_size);
if (client_socket < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
// 创建SSL连接
SSL* ssl = SSL_new(ssl_ctx);
SSL_set_fd(ssl, client_socket);
SSL_accept(ssl);
// 打开要加密的文件
FILE* input_file = fopen("input_file.txt", "rb");
if (input_file == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}
// 创建缓存区
unsigned char buffer[BUFFER_SIZE];
// 加密并发送文件
int bytes_read = 0;
int bytes_sent = 0;
do {
bytes_read = fread(buffer, 1, BUFFER_SIZE, input_file);
if (bytes_read > 0) {
int bytes_encrypted = SSL_write(ssl, buffer, bytes_read);
if (bytes_encrypted < 0) {
perror("SSL_write");
exit(EXIT_FAILURE);
}
bytes_sent += bytes_encrypted;
}
} while (bytes_read > 0);
// 关闭文件和连接
fclose(input_file);
SSL_shutdown(ssl);
SSL_free(ssl);
SSL_CTX_free(ssl_ctx);
close(client_socket);
close(server_socket);
printf("Sent %d bytes\n", bytes_sent);
return 0;
}
```
Client端接收并解密文件:
```cpp
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define IP_ADDRESS "127.0.0.1"
#define PORT 443
#define CA_CERTIFICATE "ca.crt"
#define BUFFER_SIZE 1024
int main() {
// 初始化SSL库
SSL_library_init();
// 创建SSL上下文
SSL_CTX* ssl_ctx = SSL_CTX_new(TLSv1_2_client_method());
// 加载CA证书
if (!SSL_CTX_load_verify_locations(ssl_ctx, CA_CERTIFICATE, NULL)) {
perror("SSL_CTX_load_verify_locations");
exit(EXIT_FAILURE);
}
// 创建socket
int client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
// 连接到服务器
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr(IP_ADDRESS);
server_address.sin_port = htons(PORT);
if (connect(client_socket, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
perror("connect");
exit(EXIT_FAILURE);
}
// 创建SSL连接
SSL* ssl = SSL_new(ssl_ctx);
SSL_set_fd(ssl, client_socket);
SSL_connect(ssl);
// 打开要写入的文件
FILE* output_file = fopen("output_file.txt", "wb");
if (output_file == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}
// 创建缓存区
unsigned char buffer[BUFFER_SIZE];
// 接收并解密文件
int bytes_received = 0;
int bytes_decrypted = 0;
do {
bytes_received = SSL_read(ssl, buffer, BUFFER_SIZE);
if (bytes_received > 0) {
int bytes_written = fwrite(buffer, 1, bytes_received, output_file);
if (bytes_written < bytes_received) {
perror("fwrite");
exit(EXIT_FAILURE);
}
bytes_decrypted += bytes_received;
}
} while (bytes_received > 0);
// 关闭文件和连接
fclose(output_file);
SSL_shutdown(ssl);
SSL_free(ssl);
SSL_CTX_free(ssl_ctx);
close(client_socket);
printf("Received and decrypted %d bytes\n", bytes_decrypted);
return 0;
}
```
在这个例子中,我们使用了TLSv1.2协议和HTTPS端口443。服务器使用私钥和证书来创建SSL上下文,监听端口并接受客户端连接。客户端使用SSL上下文来加载CA证书,连接到服务器并创建SSL连接。在服务器端,我们打开要加密的文件,然后将其分块加密并发送到客户端。在客户端,我们接收加密的数据,并将其解密到一个新文件中。