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(())
}
特点
- 基于rustls的高性能TLS实现
- 完全异步设计,适合I/O密集型应用
- 支持现代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
运行步骤
-
首先需要生成自签名证书(可以在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"
-
启动服务器:
cargo run --bin server
-
在另一个终端运行客户端:
cargo run --bin client
这个完整示例展示了如何使用async-rustls实现一个简单的加密通信应用,包括证书处理、TLS连接建立和数据传输。服务器会回显客户端发送的所有数据,演示了基本的加密通信流程。