Rust异步TLS库async-rustls的使用:高性能安全的异步加密通信实现

Rust异步TLS库async-rustls的使用:高性能安全的异步加密通信实现

async-rustls是一个基于rustls的异步TLS/SSL流库,但请注意该项目已标记为deprecated,推荐使用futures-rustls作为替代。

许可证

该项目采用双重许可:

  • Apache License, Version 2.0
  • MIT license

示例代码

以下是一个使用async-rustls实现TLS客户端和服务器通信的完整示例:

TLS服务器示例

use async_std::net::{TcpListener, TcpStream};
use async_std::prelude::*;
use async_std::task;
use rustls::ServerConfig;
use async_rustls::TlsAcceptor;

#[async_std::main]
async fn main() -> std::io::Result<()> {
    // 简单配置TLS
    let mut config = ServerConfig::new(rustls::NoClientAuth::new());
    
    // 加载证书和私钥
    let certs = load_certs("cert.pem");
    let key = load_private_key("key.pem");
    config.set_single_cert(certs, key).unwrap();
    
    let acceptor = TlsAcceptor::from(Arc::new(config));
    let listener = TcpListener::bind("127.0.0.1:8443").await?;
    
    while let Ok((stream, _)) = listener.accept().await {
        let acceptor = acceptor.clone();
        
        task::spawn(async move {
            let mut tls_stream = acceptor.accept(stream).await.unwrap();
            
            let mut buf = vec![0u8; 1024];
            let n = tls_stream.read(&mut buf).await.unwrap();
            println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
            
            tls_stream.write_all(b"Hello from server!\n").await.unwrap();
        });
    }
    
    Ok(())
}

fn load_certs(filename: &str) -> Vec<rustls::Certificate> {
    // 证书加载实现...
}

fn load_private_key(filename: &str) -> rustls::PrivateKey {
    // 私钥加载实现...
}

TLS客户端示例

use async_std::net::TcpStream;
use async_std::prelude::*;
use rustls::ClientConfig;
use async_rustls::TlsConnector;

#[async_std::main]
async fn main() -> stdio::Result<()> {
    // 配置TLS客户端
    let mut config = ClientConfig::new();
    
    // 设置根证书(用于验证服务器)
    let mut root_store = rustls::RootCertStore::empty();
    root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
    config.root_store = root_store;
    
    let connector = TlsConnector::from(Arc::new(config));
    let stream = TcpStream::connect("127.0.0.1:8443").await?;
    
    let domain = webpki::DNSNameRef::try_from_ascii_str("localhost").unwrap();
    let mut tls_stream = connector.connect(domain, stream).await?;
    
    tls_stream.write_all(b"Hello from client!\n").await?;
    
    let mut buf = vec![0u8; 1024];
    let n = tls_stream.read(&mut buf).await?;
    println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
    
    Ok(())
}

特点

  1. 基于rustls的高性能TLS实现
  2. 完全异步设计,适合I/O密集型应用
  3. 支持现代TLS协议和加密算法

安装

在Cargo.toml中添加依赖:

async-rustls = "0.4.2"

或者运行命令:

cargo add async-rustls

注意事项

由于async-rustls已标记为deprecated,建议新项目使用futures-rustls替代。该示例代码仅供参考如何实现异步TLS通信的基本模式。


1 回复

Rust异步TLS库async-rustls的使用:高性能安全的异步加密通信实现

介绍

async-rustls是一个基于rustls构建的异步TLS库,它提供了高性能、安全的异步加密通信能力。这个库特别适合需要处理大量并发加密连接的应用程序,如Web服务器、代理服务或任何需要安全通信的网络应用。

主要特点:

  • 基于rustls,提供可靠的安全保障
  • 与async/await语法无缝集成
  • 支持Tokio和async-std运行时
  • 零拷贝设计,性能优异
  • 现代密码套件支持

基本使用方法

添加依赖

首先在Cargo.toml中添加依赖:

[dependencies]
async-rustls = "0.23"
tokio = { version = "1.0", features = ["full"] }
rustls = "0.21"

服务端示例

use async_rustls::rustls::{Certificate, PrivateKey, ServerConfig};
use async_rustls::TlsAcceptor;
use std::fs;
use std::sync::Arc;
use tokio::net::TcpListener;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 加载证书和私钥
    let certs = load_certs("certs/server.crt")?;
    let key = load_private_key("certs/server.key")?;
    
    // 配置TLS
    let config = ServerConfig::builder()
        .with_safe_defaults()
        .with_no_client_auth()
        .with_single_cert(certs, key)?;
    let acceptor = TlsAcceptor::from(Arc::new(config));
    
    // 监听TCP连接
    let listener = TcpListener::bind("127.0.0.1:8443").await?;
    
    loop {
        let (stream, _) = listener.accept().await?;
        let acceptor = acceptor.clone();
        
        tokio::spawn(async move {
            // 接受TLS连接
            let mut tls_stream = acceptor.accept(stream).await.unwrap();
            
            // 在这里处理加密通信
            let mut buf = [0u8; 1024];
            let n = tls_stream.read(&mut buf).await.unwrap();
            println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
        });
    }
}

fn load_certs(path: &str) -> Result<Vec<Certificate>, Box<dyn std::error::Error>> {
    let certs = fs::read(path)?;
    Ok(rustls_pemfile::certs(&mut &*certs)?.into_iter().map(Certificate).collect())
}

fn load_private_key(path: &str) -> Result<PrivateKey, Box<dyn std::error::Error>> {
    let key = fs::read(path)?;
    Ok(PrivateKey(rustls_pemfile::pkcs8_private_keys(&mut &*key)?[0].clone()))
}

客户端示例

use async_rustls::rustls::{ClientConfig, RootCertStore};
use async_rustls::TlsConnector;
use tokio::net::TcpStream;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 配置信任的根证书
    let mut root_store = RootCertStore::empty();
    root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
        rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
            ta.subject,
            ta.spki,
            ta.name_constraints,
        )
    }));
    
    let config = ClientConfig::builder()
        .with_safe_defaults()
        .with_root_certificates(root_store)
        .with_no_client_auth();
    
    let connector = TlsConnector::from(Arc::new(config));
    
    // 建立TCP连接
    let stream = TcpStream::connect("127.0.0.1:8443").await?;
    
    // 建立TLS连接
    let domain = "localhost".try_into()?;
    let mut tls_stream = connector.connect(domain, stream).await?;
    
    // 发送数据
    tls_stream.write_all(b"Hello from client!").await?;
    
    Ok(())
}

高级用法

自定义密码套件

let config = ServerConfig::builder()
    .with_cipher_suites(&[
        rustls::cipher_suite::TLS13_AES_256_GCM_SHA384,
        rustls::cipher_suite::TLS13_AES_128_GCM_SHA256,
    ])
    .with_safe_default_kx_groups()
    .with_protocol_versions(&[&rustls::version极佳的选择。下面我将提供一个完整的示例,展示如何使用async-rustls构建一个简单的客户端-服务器应用。

## 完整示例

### 服务端代码 (server.rs)

```rust
use async_rustls::rustls::{Certificate, PrivateKey, ServerConfig};
use async_rustls::TlsAcceptor;
use std::fs;
use std::sync::Arc;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpListener;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 加载证书和私钥
    let certs = load_certs("certs/server.crt")?;
    let key = load_private_key("certs/server.key")?;
    
    // 配置TLS服务器
    let config = ServerConfig::builder()
        .with_safe_defaults()
        .with_no_client_auth()
        .with_single_cert(certs, key)?;
    let acceptor = TlsAcceptor::from(Arc::new(config));
    
    // 绑定TCP端口
    let listener = TcpListener::bind("127.0.0.1:8443").await?;
    println!("Server listening on 127.0.0.1:8443");
    
    loop {
        let (stream, _) = listener.accept().await?;
        let acceptor = acceptor.clone();
        
        tokio::spawn(async move {
            // 接受TLS连接
            let mut tls_stream = match acceptor.accept(stream).await {
                Ok(stream) => stream,
                Err(e) => {
                    eprintln!("Failed to accept TLS connection: {}", e);
                    return;
                }
            };
            
            // 处理客户端请求
            let mut buf = [0u8; 1024];
            loop {
                let n = match tls_stream.read(&mut buf).await {
                    Ok(0) => break, // 连接关闭
                    Ok(n) => n,
                    Err(e) => {
                        eprintln!("Read error: {}", e);
                        break;
                    }
                };
                
                // 打印接收到的数据
                println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
                
                // 回显数据给客户端
                if let Err(e) = tls_stream.write_all(&buf[..n]).await {
                    eprintln!("Write error: {}", e);
                    break;
                }
            }
        });
    }
}

// 加载证书文件
fn load_certs(path: &str) -> Result<Vec<Certificate>, Box<dyn std::error::Error>> {
    let certs = fs::read(path)?;
    Ok(rustls_pemfile::certs(&mut &*certs)?.into_iter().map(Certificate).collect())
}

// 加载私钥文件
fn load_private_key(path: &str) -> Result<PrivateKey, Box<dyn std::error::Error>> {
    let key = fs::read(path)?;
    Ok(PrivateKey(rustls_pemfile::pkcs8_private_keys(&mut &*key)?[0].clone()))
}

客户端代码 (client.rs)

use async_rustls::rustls::{ClientConfig, RootCertStore};
use async_rustls::TlsConnector;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 配置信任的根证书
    let mut root_store = RootCertStore::empty();
    root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
        rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
            ta.subject,
            ta.spki,
            ta.name_constraints,
        )
    }));
    
    // 配置TLS客户端
    let config = ClientConfig::builder()
        .with_safe_defaults()
        .with_root_certificates(root_store)
        .with_no_client_auth();
    
    let connector = TlsConnector::from(Arc::new(config));
    
    // 建立TCP连接
    let stream = TcpStream::connect("127.0.0.1:8443").await?;
    
    // 建立TLS连接
    let domain = "localhost".try_into()?;
    let mut tls_stream = connector.connect(domain, stream).await?;
    
    // 发送测试数据
    let message = b"Hello from client!";
    tls_stream.write_all(message).await?;
    println!("Sent: {}", String::from_utf8_lossy(message));
    
    // 接收服务器响应
    let mut buf = [0u8; 1024];
    let n = tls_stream.read(&mut buf).await?;
    println!("Received: {}", String::from_utf8_lossy(&buf[..n]));
    
    Ok(())
}

项目结构

async-tls-demo/
├── Cargo.toml
├── certs/
│   ├── server.crt  # 服务器证书
│   └── server.key  # 服务器私钥
├── src/
│   ├── client.rs
│   └── server.rs

运行步骤

  1. 首先需要生成自签名证书(可以在Linux/macOS上使用OpenSSL):

    mkdir -p certs
    openssl req -x509 -newkey rsa:4096 -keyout certs/server.key -out certs/server.crt -days 365 -nodes -subj "/CN=localhost"
    
  2. 启动服务器:

    cargo run --bin server
    
  3. 在另一个终端运行客户端:

    cargo run --bin client
    

这个完整示例展示了如何使用async-rustls实现一个简单的加密通信应用,包括证书处理、TLS连接建立和数据传输。服务器会回显客户端发送的所有数据,演示了基本的加密通信流程。

回到顶部