如何基于cryptlib实现自定义I/O逻辑,完成TLS加密数据处理?
解决方案
cryptlib 同时支持你提到的两种自定义I/O实现方式,具体操作如下:
方式1:自定义I/O回调(更省心,推荐)
你不需要手动处理加密数据的传递,所有网络读写逻辑都通过回调触发:
- 定义符合要求的读写回调函数,函数原型如下:
// 读回调:cryptlib需要读网络数据时调用,你需要从自定义I/O接口读最多length字节数据写入buffer,返回实际读到的字节数,出错返回负值 int myIoRead(void* customIoContext, void* buffer, int length); // 写回调:cryptlib需要写网络数据时调用,你需要把buffer中length字节数据通过自定义I/O接口发送,返回实际发送的字节数,出错返回负值 int myIoWrite(void* customIoContext, const void* buffer, int length);
- 填充
CRYPT_SESSION_INFO结构:networkRead字段填myIoRead函数指针networkWrite字段填myIoWrite函数指针cryptContext字段填你自定义I/O需要的上下文指针/句柄(会作为第一个参数传入你实现的回调)
- 调用
cryptCreateSessionEx()创建TLS会话,传入上述填充好的结构即可。后续你依旧可以像默认模式一样调用cryptPushData传入待加密的明文、cryptPopData拿解密后的明文,cryptlib会自动在需要的时候调用你实现的I/O回调完成网络读写。
方式2:手动传递加密数据(完全可控)
如果你不想用回调,完全自己控制加密数据的输入输出,用cryptPushDataRaw和cryptPopDataRaw两个API即可:
- 接收流程:
- 从自定义I/O接口读取加密的Rx数据存入缓冲区
- 调用
cryptPushDataRaw(cryptSession, 加密数据缓冲区地址, 数据长度),把加密数据喂给cryptlib处理 - 调用
cryptPopData(cryptSession, 明文缓冲区地址, 缓冲区长度),即可拿到解密后的明文数据
- 发送流程:
- 调用
cryptPushData(cryptSession, 待发送明文地址, 明文长度),把明文喂给cryptlib加密 - 调用
cryptPopDataRaw(cryptSession, 加密数据缓冲区地址, 缓冲区长度),即可拿到需要发送的加密数据 - 把拿到的加密数据通过自定义I/O接口发送出去
- 调用
补充说明:TLS握手阶段逻辑和业务数据传输逻辑完全一致,不需要额外特殊处理。比如初始化会话后第一次调用cryptPopDataRaw就会拿到待发送的ClientHello握手包,你发出去后把收到的握手响应数据调用cryptPushDataRaw喂给cryptlib,反复上述交互直到握手完成,之后就可以正常传输业务数据。官方示例没写手动喂数据的步骤,是因为那些示例默认你已经把自定义套接字句柄通过cryptSetAttribute接口传给了cryptlib,cryptlib内部会自动从你传入的句柄读数据,不需要手动调用Raw接口。
内容的提问来源于stack exchange,提问作者dialer
相关产品推荐
相关产品推荐

