DTLS
DTLS是TLS的数据报版本,为UDP等不可靠传输协议提供安全保障,适用于实时通信场景。
DTLS支持的场景
| 方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 文件描述符 | 标准网络应用 | 简单直接 | 依赖系统socket |
| 内存BIO | 应用层协议、测试 | 灵活、可测试 | 需要手段管理缓冲区 |
| 自定义回调 | 嵌入式、RTOS | 完全控制 | 实现复杂 |
| 数据包队列 | 异步处理、多线程 | 解耦收发 | 需要队列管理 |
| 低级加密API | 自定义协议 | 性能最优 | 失去TLS握手等功能 |
C层面
文件描述符
#include <wolfssl/options.h>
#include <wolfssl/ssl.h>
#include <sys/socket.h>
#include <netinet/in.h>
// 初始化 WolfSSL 库
wolfSSL_Init();
// 创建 DTLS 上下文
WOLFSSL_CTX* ctx;
// 服务器端
ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method());
// 加载服务器证书
wolfSSL_CTX_use_certificate_file(ctx, "server-cert.pem",
SSL_FILETYPE_PEM);
// 加载私钥
wolfSSL_CTX_use_PrivateKey_file(ctx, "server-key.pem",
SSL_FILETYPE_PEM);
// 创建 UDP socket
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in servAddr;
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(11111);
servAddr.sin_addr.s_addr = INADDR_ANY;
bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr));
// 创建 WOLFSSL 对象
WOLFSSL* ssl = wolfSSL_new(ctx);
// 设置文件描述符
wolfSSL_set_fd(ssl, sockfd);
// 接受 DTLS 连接
struct sockaddr_in clientAddr;
socklen_t clientLen = sizeof(clientAddr);
// 接收客户端数据以获取地址
char buffer[1024];
recvfrom(sockfd, buffer, sizeof(buffer), MSG_PEEK,
(struct sockaddr*)&clientAddr, &clientLen);
// 连接到客户端地址
connect(sockfd, (struct sockaddr*)&clientAddr, clientLen);
// 执行 DTLS 握手
if (wolfSSL_accept(ssl) != SSL_SUCCESS) {
int err = wolfSSL_get_error(ssl, 0);
char errorString[80];
wolfSSL_ERR_error_string(err, errorString);
printf("错误: %s
", errorString);
}
// 接收数据
char recvBuf[1024];
int recvLen = wolfSSL_read(ssl, recvBuf, sizeof(recvBuf)-1);
if (recvLen > 0) {
recvBuf[recvLen] = '\0';
printf("接收: %s
", recvBuf);
}
// 发送数据
const char* reply = "Hello from DTLS server";
wolfSSL_write(ssl, reply, strlen(reply));
#include <wolfssl/options.h>
#include <wolfssl/ssl.h>
#include <sys/socket.h>
#include <netinet/in.h>
// 初始化 WolfSSL 库
wolfSSL_Init();
// 创建 DTLS 上下文
WOLFSSL_CTX* ctx;
// 客户端
ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method());
// 创建 UDP socket
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in servAddr;
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(11111);
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// 连接到服务器
connect(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr));
// 创建 DTLS 上下文和 SSL 对象
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method());
WOLFSSL* ssl = wolfSSL_new(ctx);
// 设置文件描述符
wolfSSL_set_fd(ssl, sockfd);
// 执行 DTLS 握手
if (wolfSSL_connect(ssl) != SSL_SUCCESS) {
int err = wolfSSL_get_error(ssl, 0);
printf("DTLS 连接失败
");
return -1;
}
// 发送数据
const char* message = "Hello from DTLS client";
wolfSSL_write(ssl, message, strlen(message));
// 接收响应
char buffer[1024];
int recvLen = wolfSSL_read(ssl, buffer, sizeof(buffer)-1);
if (recvLen > 0) {
buffer[recvLen] = '\0';
printf("接收: %s
", buffer);
}
内存BIO
#include <wolfssl/ssl.h>
// 创建 SSL 对象
WOLFSSL* ssl = wolfSSL_new(ctx);
// 设置为内存 BIO 模式
wolfSSL_SetIOReadCtx(ssl, NULL);
wolfSSL_SetIOWriteCtx(ssl, NULL);
// 使用内存缓冲区接收数据
unsigned char encryptedData[2048];
int encryptedLen = /* 从网络接收的加密数据 */;
// 将加密数据送入 WolfSSL
wolfSSL_BIO_write(ssl, encryptedData, encryptedLen);
// 读取解密后的数据
unsigned char plaintext[1024];
int plaintextLen = wolfSSL_read(ssl, plaintext, sizeof(plaintext));
// 发送数据
const char* message = "Hello";
wolfSSL_write(ssl, message, strlen(message));
// 获取加密后的数据
unsigned char outputBuffer[2048];
int outputLen = wolfSSL_BIO_read(ssl, outputBuffer, sizeof(outputBuffer));
// 然后通过自定义方式发送 outputBuffer
自定义回调
// 定义自定义接收回调
int MyReceiveCallback(WOLFSSL* ssl, char* buf, int sz, void* ctx) {
// ctx 是自定义上下文
MyContext* myCtx = (MyContext*)ctx;
// 从自定义源读取数据(如队列、缓冲区等)
int bytesRead = MyCustomRead(myCtx, buf, sz);
if (bytesRead == 0) {
return WOLFSSL_CBIO_ERR_WANT_READ; // 需要更多数据
}
return bytesRead;
}
// 定义自定义发送回调
int MySendCallback(WOLFSSL* ssl, char* buf, int sz, void* ctx) {
MyContext* myCtx = (MyContext*)ctx;
// 发送到自定义目标
int bytesSent = MyCustomWrite(myCtx, buf, sz);
if (bytesSent < 0) {
return WOLFSSL_CBIO_ERR_WANT_WRITE;
}
return bytesSent;
}
// 注册回调函数
wolfSSL_CTX_SetIORecv(ctx, MyReceiveCallback);
wolfSSL_CTX_SetIOSend(ctx, MySendCallback);
// 设置自定义上下文
MyContext myContext;
wolfSSL_SetIOReadCtx(ssl, &myContext);
wolfSSL_SetIOWriteCtx(ssl, &myContext);
// 正常使用 wolfSSL_read/write
wolfSSL_read(ssl, buffer, size);
wolfSSL_write(ssl, data, len);
数据包队列
typedef struct PacketQueue {
unsigned char* data;
int length;
struct PacketQueue* next;
} PacketQueue;
PacketQueue* rxQueue = NULL;
PacketQueue* txQueue = NULL;
int QueueReceiveCallback(WOLFSSL* ssl, char* buf, int sz, void* ctx) {
if (!rxQueue) {
return WOLFSSL_CBIO_ERR_WANT_READ;
}
PacketQueue* pkt = rxQueue;
int copyLen = (pkt->length < sz) ? pkt->length : sz;
memcpy(buf, pkt->data, copyLen);
// 从队列移除
rxQueue = pkt->next;
free(pkt->data);
free(pkt);
return copyLen;
}
int QueueSendCallback(WOLFSSL* ssl, char* buf, int sz, void* ctx) {
// 添加到发送队列
PacketQueue* pkt = malloc(sizeof(PacketQueue));
pkt->data = malloc(sz);
memcpy(pkt->data, buf, sz);
pkt->length = sz;
pkt->next = NULL;
// 加入队列尾部
AddToTxQueue(pkt);
return sz;
}
低级加密API
#include <wolfssl/wolfcrypt/aes.h>
#include <wolfssl/wolfcrypt/chacha20_poly1305.h>
// AES-GCM 示例
Aes aes;
byte key[16];
byte iv[12];
byte authTag[16];
byte plaintext[128];
byte ciphertext[128];
byte authIn[20]; // 附加认证数据
// 初始化
wc_AesGcmSetKey(&aes, key, sizeof(key));
// 加密
wc_AesGcmEncrypt(&aes, ciphertext, plaintext, sizeof(plaintext),
iv, sizeof(iv), authTag, sizeof(authTag),
authIn, sizeof(authIn));
// 解密
int ret = wc_AesGcmDecrypt(&aes, plaintext, ciphertext, sizeof(ciphertext),
iv, sizeof(iv), authTag, sizeof(authTag),
authIn, sizeof(authIn));
Was this page helpful?
Last updated today
Built with Documentation.AI