Rust异步TLS加密通信库tokio-tls-api的使用,支持Tokio生态的高性能安全传输层实现

Rust异步TLS加密通信库tokio-tls-api的使用,支持Tokio生态的高性能安全传输层实现

安装

在项目目录中运行以下Cargo命令:

cargo add tokio-tls-api

或者在Cargo.toml中添加以下行:

tokio-tls-api = "0.2.1"

示例代码

以下是一个使用tokio-tls-api进行异步TLS加密通信的完整示例:

use tokio::net::TcpStream;
use tokio_tls_api::TlsConnector;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建TCP连接
    let tcp_stream = TcpStream::connect("example.com:443").await?;
    
    // 创建TLS连接器
    let connector = TlsConnector::builder()?
        .build()?;
    
    // 建立TLS连接
    let domain = "example.com".to_string();
    let tls_stream = connector.connect(&domain, tcp_stream).await?;
    
    // 现在可以使用tls_stream进行加密通信
    // 例如:
    // tls_stream.write_all(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n").await?;
    // let mut buf = [0; 1024];
    // let n = tls_stream.read(&mut buf).await?;
    // println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
    
    Ok(())
}

下面是一个更完整的示例代码,包含实际的HTTP请求和响应处理:

use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;
use tokio_tls_api::TlsConnector;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建TCP连接
    let tcp_stream = TcpStream::connect("example.com:443").await?;
    
    // 创建TLS连接器
    let connector = TlsConnector::builder()?
        .build()?;
    
    // 建立TLS连接
    let domain = "example.com";
    let mut tls_stream = connector.connect(domain, tcp_stream).await?;
    
    // 发送HTTP GET请求
    let request = format!(
        "GET / HTTP/1.1\r\n\
         Host: {}\r\n\
         Connection: close\r\n\
         \r\n",
        domain
    );
    tls_stream.write_all(request.as_bytes()).await?;
    
    // 读取响应
    let mut response = Vec::new();
    tls_stream.read_to_end(&mut response).await?;
    
    // 打印响应内容
    println!("{}", String::from_utf8_lossy(&response));
    
    Ok(())
}

功能说明

tokio-tls-api是一个为Tokio生态系统提供的高性能异步TLS加密通信库,主要特点包括:

  1. 支持异步I/O操作
  2. 与Tokio运行时无缝集成
  3. 提供TLS客户端和服务器功能
  4. 支持多种TLS后端实现

许可证

该项目采用MIT或Apache-2.0许可证。

所有者

  • Stepan Koltsov (stepancheg)

分类

  • 异步编程
  • 网络编程

1 回复

以下是基于提供内容的完整示例demo,展示了tokio-tls-api的完整使用场景:

完整TLS客户端/服务端示例

TLS客户端完整示例

use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;
use tokio_tls_api::TlsConnector;

async fn tls_client_example() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 建立TCP连接
    let tcp_stream = TcpStream::connect("localhost:8443").await?;
    
    // 2. 创建TLS连接器
    let connector = TlsConnector::builder()
        .danger_accept_invalid_certs(true) // 仅测试用,生产环境应移除
        .build()?;
    
    // 3. 建立TLS连接
    let domain = "localhost".to_string();
    let mut tls_stream = connector.connect(&domain, tcp_stream).await?;
    
    // 4. 发送数据
    tls_stream.write_all(b"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n").await?;
    
    // 5. 接收响应
    let mut buf = [0u8; 1024];
    let n = tls_stream.read(&mut buf).await?;
    println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
    
    Ok(())
}

#[tokio::main]
async fn main() {
    if let Err(e) = tls_client_example().await {
        eprintln!("Client error: {}", e);
    }
}

TLS服务端完整示例

use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpListener;
use tokio_tls_api::TlsAcceptor;
use std::fs::File;
use std::io::Read;

async fn tls_server_example() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 加载证书和私钥
    let mut cert_file = File::open("cert.pem")?;
    let mut cert = Vec::new();
    cert_file.read_to_end(&mut cert)?;
    
    let mut key_file = File::open("key.pem")?;
    let mut key = Vec::new();
    key_file.read_to_end(&mut key)?;
    
    // 2. 创建TLS接收器
    let acceptor = TlsAcceptor::builder()
        .identity(&cert, &key)?
        .build()?;
    
    // 3. 监听TCP连接
    let listener = TcpListener::bind("0.0.0.0:8443").await?;
    println!("Server listening on 0.0.0.0:8443");
    
    loop {
        let (tcp_stream, _) = listener.accept().await?;
        let acceptor = acceptor.clone();
        
        tokio::spawn(async move {
            // 4. 接受TLS连接
            match acceptor.accept(tcp_stream).await {
                Ok(mut tls_stream) => {
                    // 5. 处理连接
                    let mut buf = [0u8; 1024];
                    match tls_stream.read(&mut buf).await {
                        Ok(n) if n > 0 => {
                            println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
                            let response = b"HTTP/1.1 200 OK\r\n\r\nHello from TLS server!";
                            tls_stream.write_all(response).await.unwrap();
                        }
                        _ => {}
                    }
                }
                Err(e) => eprintln!("TLS handshake failed: {}", e),
            }
        });
    }
}

#[tokio::main]
async fn main() {
    if let Err(e) = tls_server_example().await {
        eprintln!("Server error: {}", e);
    }
}

双向认证完整示例

use tokio::net::TcpStream;
use tokio_tls_api::TlsConnector;
use std::sync::Arc;
use rustls::{ClientConfig, RootCertStore, Certificate, PrivateKey};
use std::fs::File;
use std::io::Read;

async fn mutual_tls_client() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 加载客户端证书和私钥
    let mut client_cert = File::open("client.pem")?;
    let mut client_key = File::open("client-key.pem")?;
    let mut cert_chain = Vec::new();
    client_cert.read_to_end(&mut cert_chain)?;
    let mut key_data = Vec::new();
    client_key.read_to_end(&mut key_data)?;
    
    // 2. 加载CA证书
    let mut ca_cert = File::open("ca.pem")?;
    let mut ca_data = Vec::new();
    ca_cert.read_to_end(&mut ca_data)?;
    
    // 3. 配置TLS
    let mut config = ClientConfig::builder()
        .with_safe_defaults()
        .with_root_certificates({
            let mut store = RootCertStore::empty();
            store.add(&Certificate(ca_data))?;
            store
        })
        .with_client_auth_cert(
            vec![Certificate(cert_chain)],
            PrivateKey(key_data)
        )?;
    
    // 4. 创建连接器
    let connector = TlsConnector::from(Arc::new(config));
    
    // 5. 建立连接
    let tcp_stream = TcpStream::connect("localhost:8443").await?;
    let domain = "localhost".to_string();
    let _tls_stream = connector.connect(&domain, tcp_stream).await?;
    
    Ok(())
}

这些示例完整展示了tokio-tls-api的核心功能,包括基础TLS通信、双向认证等场景。使用时请注意:

  1. 准备相应的证书文件(cert.pem, key.pem等)
  2. 生产环境应移除危险选项如danger_accept_invalid_certs
  3. 根据实际需求调整加密套件和TLS版本
回到顶部