使用 OpenSSL 库创建 HTTPS 服务器

网上现存的大部分 OpenSSL 示例都是通过 C/C++ 编写的,本文通过更加现代的 Rust 语言来实现一个简单的 HTTPS 服务器,程序更加简洁精炼。

随着大家对网络安全的日益重视,大部分 Web 应用都开始使用 HTTPS 取代 HTTP 以提供更安全的服务。 OpenSSL 是一个封装了很多安全加密算法的类库,使用它只需要几行代码就可以给现有的 Web 应用加上安全保护。

生成加密所需的公钥和私钥

$ openssl req -x509 -newkey rsa:2048 -days 3650 -nodes \
-keyout server-key.pem -out server-cert.pem

其中 server-key.pem 存储了私钥信息, server-cert.pem 存储的是公钥信息。

在项目中添加 OpenSSL 依赖,在 Cargo.toml 文件中添加如下信息即可

[dependencies]
openssl = "0.10.5"

实现代码

extern crate openssl;

use openssl::ssl::{Error, SslAcceptor, SslFiletype, SslMethod, SslStream};
use std::net::{TcpListener, TcpStream};
use std::sync::Arc;
use std::thread;
use std::str;

fn main() {
let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
acceptor
.set_private_key_file("server-key.pem", SslFiletype::PEM)
.unwrap();
acceptor
.set_certificate_chain_file("server-cert.pem")
.unwrap();
acceptor.check_private_key().unwrap();
let acceptor = Arc::new(acceptor.build());

let listener = TcpListener::bind("0.0.0.0:8443").unwrap();

println!("server is up");

fn write_response(stream: &mut SslStream<TcpStream>) -> Result<usize, Error> {
let mut len = 0;
len += stream.ssl_write(b"HTTP/1.1 200 OK\r\n")?;
len += stream.ssl_write(b"Content-Length: 10\r\n")?;
len += stream.ssl_write(b"Content-Type: text/html\r\n\r\n")?;
len += stream.ssl_write(b"hello rust")?;
Ok(len)
}

fn handle_requset(stream: &mut SslStream<TcpStream>) -> Result<usize, Error> {
let mut buffer = [0; 100];
stream.ssl_read(&mut buffer)?;

println!("request: {:?}", str::from_utf8(&buffer).unwrap());