- 初始化SSL库:
- 在C语言中,使用OpenSSL库时,首先调用
SSL_library_init()
函数来初始化SSL库,该函数会初始化加密算法、错误处理等相关机制。
- 示例代码(C语言,OpenSSL库):
#include <openssl/ssl.h>
#include <openssl/err.h>
int main() {
SSL_library_init();
// 后续代码
return 0;
}
- 创建SSL上下文:
- 使用
SSL_CTX_new()
函数创建SSL上下文。根据使用的协议版本不同(如TLSv1.2、TLSv1.3等),选择对应的方法。例如,使用TLSv1.2协议,可以调用SSL_CTX_new(TLSv1_2_server_method())
创建服务器端上下文,SSL_CTX_new(TLSv1_2_client_method())
创建客户端上下文。
- 示例代码(服务器端,C语言,OpenSSL库):
SSL_CTX *ctx;
ctx = SSL_CTX_new(TLSv1_2_server_method());
if (ctx == NULL) {
ERR_print_errors_fp(stderr);
return 1;
}
- 加载证书和私钥:
- 服务器端:
- 使用
SSL_CTX_use_certificate_file()
函数加载服务器证书文件,该文件包含公钥等信息。例如SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM);
,其中"server.crt"
是证书文件名,SSL_FILETYPE_PEM
表示证书格式为PEM格式。
- 使用
SSL_CTX_use_PrivateKey_file()
函数加载服务器私钥文件,如SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM);
,同样"server.key"
是私钥文件名,SSL_FILETYPE_PEM
是格式。
- 验证私钥与证书是否匹配,可使用
SSL_CTX_check_private_key()
函数。如果不匹配,会返回0,需要检查证书和私钥。
- 客户端:
- 若需要验证服务器证书,加载CA(证书颁发机构)证书,使用
SSL_CTX_load_verify_locations()
函数,例如SSL_CTX_load_verify_locations(ctx, "ca.crt", NULL);
,"ca.crt"
是CA证书文件名,第二个参数为目录路径,这里设为NULL。
- 建立TCP连接:
- 使用传统的TCP Socket编程方法,如
socket()
、bind()
、listen()
(服务器端)、connect()
(客户端)来建立TCP连接。
- 示例代码(服务器端,C语言):
int sockfd, newsockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("Socket creation failed");
return 1;
}
// 绑定、监听等操作
- 创建SSL对象并关联到TCP Socket:
- 使用
SSL_new()
函数创建SSL对象,并使用SSL_set_fd()
函数将SSL对象与已建立的TCP Socket关联。
- 示例代码(服务器端,C语言):
SSL *ssl;
ssl = SSL_new(ctx);
if (ssl == NULL) {
ERR_print_errors_fp(stderr);
return 1;
}
SSL_set_fd(ssl, newsockfd);
- 进行SSL/TLS握手:
- 服务器端:调用
SSL_accept()
函数进行握手,等待客户端连接并完成握手过程。
- 客户端:调用
SSL_connect()
函数发起握手,尝试与服务器建立安全连接。
- 示例代码(服务器端,C语言):
if (SSL_accept(ssl) <= 0) {
ERR_print_errors_fp(stderr);
// 处理握手失败
}
- 数据传输:
- 握手成功后,使用
SSL_write()
和SSL_read()
函数进行安全的数据传输,替代传统的send()
和recv()
函数。
- 示例代码(服务器端发送数据,C语言):
const char *msg = "Hello, client!";
int bytes_sent = SSL_write(ssl, msg, strlen(msg));
if (bytes_sent <= 0) {
ERR_print_errors_fp(stderr);
// 处理发送失败
}
- 关闭连接:
- 使用
SSL_shutdown()
函数关闭SSL连接,然后使用close()
函数关闭TCP Socket。
- 示例代码(服务器端,C语言):
SSL_shutdown(ssl);
close(newsockfd);
SSL_free(ssl);
SSL_CTX_free(ctx);