Rust异步TLS库async-tls的使用:安全高效的加密通信解决方案

async-tls

使用 Rustls 的异步 TLS/SSL 流。

Crates.io version Download docs.rs docs chat

API Docs | Releases | Contributing

维护通知

我,Florian Gilcher,目前是 async-tls 的主要维护者。由于一般工作负荷,我希望将维护工作交给其他人,以继续 async-tls 的总体愿景:

  • 运行时独立性
  • 后端独立性(目前未实现)
  • 专注于基于用例的配置,而不是暴露所有配置

我希望申请维护者职位的人能够承诺至少每周投入 4 小时的时间,因此我建议首先获得企业支持。这个数字并不严格,但我希望这个过程能够改善维护。我很高兴有一组多个维护者。

我承诺在最初的两个月内每周提供 30 分钟的反馈 - 在交接的最初几天会更多。

如果有兴趣,请通过电子邮件与我联系。

特性

async-tls 可以在服务器和客户端程序中使用。为了节省编译时间,您可以关闭部分功能以加快编译时间。

如果仅在客户端使用 async-tls,请停用默认功能并使用 “client” 功能。

[dependencies.async-tls]
version = "0.8"
default-features = false
features = ["client"]

如果仅在服务器端使用 async-tls,请停用默认功能并使用 “server” 功能。

[dependencies.async-tls]
version = "0.8"
default-features = false
features = ["server"]

简单客户端

use async_tls::TlsConnector;
use async_std::net::TcpStream;

// ...

let tcp_stream = TcpStream::connect("rust-lang.org:443").await?;
let connector = TlsConnector::default();
let mut tls_stream = connector.connect("www.rust-lang.org", tcp_stream).await?;

// ...

客户端示例程序

请参阅 examples/client。您可以使用以下命令运行它:

cd examples/client
cargo run -- hsts.badssl.com

服务器示例程序

请参阅 examples/server。您可以使用以下命令运行它:

cd examples/server
cargo run -- 127.0.0.1:8080 --cert ../../tests/end.cert --key ../../tests/end.rsa

并使用以下命令将客户端指向它:

cd examples/client
cargo run -- 127.0.0.1 --port 8080 --domain localhost --cafile ../../tests/end.chain

注意:除了测试之外,切勿在任何地方使用这些证书文件!

安全性

此 crate 使用 #![deny(unsafe_code)] 来确保所有内容均以 100% 安全 Rust 实现。

许可证与来源

此项目根据以下任一许可证授权:

  • Apache 许可证,版本 2.0
  • MIT 许可证

由您选择。

这最初是 tokio-rustls 的一个分支。

贡献

除非您明确声明,否则根据 Apache-2.0 许可证定义,您为包含在 async-tls 中而有意提交的任何贡献均应按照上述双重许可,不附加任何额外条款或条件。

完整客户端示例代码:

use async_tls::TlsConnector;
use async_std::net::TcpStream;
use async_std::io::{self, Read, Write};
use std::error::Error;

#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // 建立TCP连接
    let tcp_stream = TcpStream::connect("rust-lang.org:443").await?;
    
    // 创建TLS连接器
    let connector = TlsConnector::default();
    
    // 建立TLS连接
    let mut tls_stream = connector.connect("www.rust-lang.org", tcp_stream).await?;
    
    // 构造HTTP请求
    let request = "GET / HTTP/1.1\r\nHost: www.rust-lang.org\r\nConnection: close\r\n\r\n";
    
    // 发送HTTP请求
    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(())
}

完整服务器示例代码:

use async_tls::TlsAcceptor;
use async_std::net::{TcpListener, TcpStream};
use async_std::io::{self, Read, Write};
use async_std::prelude::*;
use rustls_pemfile::{certs, rsa_private_keys};
use std::error::Error;
use std::fs::File;
use std::io::BufReader;

#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // 加载证书和私钥
    let cert_file = &mut BufReader::new(File::open("cert.pem")?);
    let key_file = &mut BufReader::new(File::open("key.pem")?);
    
    let cert_chain = certs(cert_file)?.into_iter().map(rustls::Certificate).collect();
    let mut keys = rsa_private_keys(key_file)?;
    
    // 创建TLS配置
    let config = rustls::ServerConfig::builder()
        .with_safe_defaults()
        .with_no_client_auth()
        .with_single_cert(cert_chain, rustls::PrivateKey(keys.remove(0)))?;
    
    // 创建TLS接收器
    let acceptor = TlsAcceptor::from(std::sync::Arc::new(config));
    
    // 监听TCP连接
    let listener = TcpListener::bind("127.0.0.1:8443").await?;
    
    println!("Server listening on 127.0.0.1:8443");
    
    while let Ok((stream, _)) = listener.accept().await {
        let acceptor = acceptor.clone();
        
        async_std::task::spawn(async move {
            if let Err(e) = handle_client(acceptor, stream).await {
                eprintln!("Error handling client: {}", e);
            }
        });
    }
    
    Ok(())
}

async fn handle_client(acceptor: TlsAcceptor, stream: TcpStream) -> Result<(), Box<dyn Error>> {
    // 接受TLS连接
    let mut tls_stream = acceptor.accept(stream).await?;
    
    // 读取客户端请求
    let mut buffer = [0; 1024];
    let bytes_read = tls_stream.read(&mut buffer).await?;
    
    let request = String::from_utf8_lossy(&buffer[..bytes_read]);
    println!("Received request:\n{}", request);
    
    // 发送HTTP响应
    let response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nHello World!";
    tls_stream.write_all(response.as_bytes()).await?;
    tls_stream.flush().await?;
    
    Ok(())
}

1 回复

Rust异步TLS库async-tls的使用指南

概述

async-tls是一个基于Rust异步生态系统的TLS库,提供安全高效的加密通信解决方案。它建立在async-std和tokio运行时之上,与Rust的异步/等待语法完美集成。

主要特性

  • 支持TLS 1.2和TLS 1.3协议
  • 零拷贝IO操作
  • 与async-std和tokio运行时兼容
  • 支持客户端和服务器端TLS连接
  • 提供证书验证和密钥管理功能

安装方法

在Cargo.toml中添加依赖:

[dependencies]
async-tls = "0.11"
async-std = { version = "1.9", features = ["attributes"] }

基本使用方法

1. 客户端示例

use async_tls::TlsConnector;
use async_std::net::TcpStream;
use async_std::prelude::*;

#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 建立TCP连接
    let stream = TcpStream::connect("example.com:443").await?;
    
    // 创建TLS连接器
    let connector = TlsConnector::new();
    
    // 建立TLS连接
    let mut tls_stream = connector.connect("example.com", stream).await?;
    
    // 发送HTTPS请求
    tls_stream.write_all(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n").await?;
    
    // 读取响应
    let mut response = Vec::new();
    tls_stream.read_to_end(&mut response).await?;
    
    println!("Response: {}", String::from_utf8_lossy(&response));
    Ok(())
}

2. 服务器端示例

use async_tls::{TlsAcceptor, TlsStream};
use async_std::net::{TcpListener, TcpStream};
use async_std::prelude::*;
use async_std::task;
use std::sync::Arc;

#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 加载证书和私钥
    let cert = include_bytes!("cert.pem");
    let key = include_bytes!("key.pem");
    
    let acceptor = TlsAcceptor::new(cert, key)?;
    let listener = TcpListener::bind("0.0.0.0:8443").await?;
    
    while let Ok((stream, _)) = listener.accept().await {
        let acceptor = acceptor.clone();
        
        task::spawn(async move {
            if let Ok(mut tls_stream) = acceptor.accept(stream).await {
                // 处理TLS连接
                let mut buf = [0u8; 1024];
                if let Ok(n) = tls_stream.read(&mut buf).await {
                    println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
                }
            }
        });
    }
    
    Ok(())
}

高级配置

自定义TLS配置

use async_tls::TlsConnector;
use rustls::ClientConfig;

let mut config = ClientConfig::new();
// 自定义TLS配置
let connector = TlsConnector::from(Arc::new(config));

证书验证

use async_tls::TlsConnector;
use std::sync::Arc;

let connector = TlsConnector::new()
    .danger_accept_invalid_certs(true) // 仅用于测试环境
    .danger_accept_invalid_hostnames(true);

性能优化建议

  1. 复用TlsConnector和TlsAcceptor实例
  2. 使用连接池管理TLS连接
  3. 适当调整缓冲区大小
  4. 启用零拷贝特性减少内存复制

注意事项

  • 生产环境务必使用有效的证书
  • 注意处理TLS握手失败的情况
  • 定期更新依赖库以获取安全补丁
  • 合理设置超时和重试机制

async-tls库为Rust异步应用程序提供了强大而灵活的TLS支持,能够满足各种安全通信场景的需求。

完整示例代码

客户端完整示例

use async_tls::TlsConnector;
use async_std::net::TcpStream;
use async_std::prelude::*;
use std::error::Error;

#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // 建立TCP连接到HTTPS服务器
    let tcp_stream = TcpStream::connect("httpbin.org:443").await?;
    
    // 创建TLS连接器实例
    let connector = TlsConnector::new();
    
    // 建立TLS加密连接
    let mut tls_stream = connector.connect("httpbin.org", tcp_stream).await?;
    
    // 构造HTTP GET请求
    let request = "GET /json HTTP/1.1\r\nHost: httpbin.org\r\nAccept: application/json\r\nConnection: close\r\n\r\n";
    
    // 发送HTTP请求
    tls_stream.write_all(request.as_bytes()).await?;
    
    // 读取服务器响应
    let mut response = Vec::new();
    tls_stream.read_to_end(&mut response).await?;
    
    // 输出响应内容
    println!("HTTP响应:\n{}", String::from_utf8_lossy(&response));
    
    Ok(())
}

服务器端完整示例

use async_tls::{TlsAcceptor, TlsStream};
use async_std::net::{TcpListener, TcpStream};
use async_std::prelude::*;
use async_std::task;
use std::sync::Arc;
use std::error::Error;

// 示例证书和私钥(测试用途)
const TEST_CERT: &[u8] = include_bytes!("../test_certs/cert.pem");
const TEST_KEY: &[u8] = include_bytes!("../test_certs/key.pem");

#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // 创建TLS接收器
    let acceptor = TlsAcceptor::new(TEST_CERT, TEST_KEY)?;
    let acceptor = Arc::new(acceptor);
    
    // 绑定监听端口
    let listener = TcpListener::bind("127.0.0.1:8443").await?;
    println!("TLS服务器启动在: 127.0.0.1:8443");
    
    // 接受客户端连接
    while let Ok((stream, addr)) = listener.accept().await {
        println!("接收到来自 {} 的连接", addr);
        
        let acceptor = acceptor.clone();
        
        // 为每个连接创建异步任务
        task::spawn(async move {
            match acceptor.accept(stream).await {
                Ok(mut tls_stream) => {
                    println!("TLS握手成功: {}", addr);
                    
                    // 读取客户端数据
                    let mut buffer = [0u8; 1024];
                    match tls_stream.read(&mut buffer).await {
                        Ok(n) if n > 0 => {
                            let received = String::from_utf8_lossy(&buffer[..n]);
                            println!("接收到数据 ({}字节): {}", n, received);
                            
                            // 发送响应
                            let response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello from TLS Server!";
                            if let Err(e) = tls_stream.write_all(response.as_bytes()).await {
                                eprintln!("发送响应失败: {}", e);
                            }
                        }
                        Ok(_) => println!("连接已关闭: {}", addr),
                        Err(e) => eprintln!("读取数据错误: {}", e),
                    }
                }
                Err(e) => eprintln!("TLS握手失败: {} - {}", addr, e),
            }
        });
    }
    
    Ok(())
}

自定义配置示例

use async_tls::TlsConnector;
use rustls::{ClientConfig, RootCertStore};
use std::sync::Arc;
use std::error::Error;

async fn create_custom_connector() -> Result<TlsConnector, Box<dyn Error>> {
    // 创建自定义客户端配置
    let mut config = ClientConfig::new();
    
    // 配置根证书存储
    let mut root_store = RootCertStore::empty();
    // 这里可以添加自定义根证书
    
    // 创建自定义连接器
    let connector = TlsConnector::from(Arc::new(config));
    
    Ok(connector)
}

// 使用自定义连接器的示例
#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let connector = create_custom_connector().await?;
    
    // 使用自定义连接器建立连接
    let stream = async_std::net::TcpStream::connect("example.com:443").await?;
    let mut tls_stream = connector.connect("example.com", stream).await?;
    
    // 进行通信...
    
    Ok(())
}
回到顶部