logo
WolfSSLDTLS

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));

内存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));