调用我的基于hyper
的API现在已移植到HTTPS,使用Python的requests
SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)'
的每个请求。
根据tokio_rustls
的文档:
Certificate
必须为DER-encoded X.509PrivateKey
必须是DER-encoded ASN.1 in either PKCS#8 or PKCS#1 format。
我在PKEY
和CERT
变量中使用的密钥是certbot
生成的.pem
密钥,使用以下命令转换为.der
:
x1米11米1xopenssl pkcs8 -topk8 -inform PEM -outform DER -in /etc/letsencrypt/live/mysite.com/privkey.pem -out /etc/letsencrypt/live/mysite.com/privkey.der -nocrypt
并加载了include_bytes!()
宏。
它会编译、轮询......并且在调用者获得开头提到的SSLError
时,在每个请求Bad connection: cannot decrypt peer's message
时都会抛出此错误。
下面是用于API的脚本:
fn tls_acceptor_impl(cert_der: &[u8], key_der: &[u8]) -> tokio_rustls::TlsAcceptor {
let key = PrivateKey(cert_der.into());
let cert = Certificate(key_der.into());
Arc::new(
ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(vec![cert], key)
.unwrap(),
)
.into()
}
fn tls_acceptor() -> tokio_rustls::TlsAcceptor {
tls_acceptor_impl(PKEY, CERT)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let addr = SocketAddr::from(...);
let mut listener = tls_listener::builder(tls_acceptor())
.max_handshakes(10)
.listen(AddrIncoming::bind(&addr).unwrap());
let (tx, mut rx) = mpsc::channel::<tokio_rustls::TlsAcceptor>(1);
let http = Http::new();
loop {
tokio::select! {
conn = listener.accept() => {
match conn.expect("Tls listener stream should be infinite") {
Ok(conn) => {
let http = http.clone();
// let tx = tx.clone();
// let counter = counter.clone();
tokio::spawn(async move {
// let svc = service_fn(move |request| handle_request(tx.clone(), counter.clone(), request));
if let Err(err) = http.serve_connection(conn, service_fn(my_query_handler)).await {
eprintln!("Application error: {}", err);
}
});
},
Err(e) => {
eprintln!("Bad connection: {}", e);
}
}
},
message = rx.recv() => {
// Certificate is loaded on another task; we don't want to block the listener loop
let acceptor = message.expect("Channel should not be closed");
}
}
}
当证书密钥在Web上工作时(因为它们是apache2
服务器的密钥),我如何理解这些错误?我尝试了各种其他编码,这些编码与文档相反,都以同样的方式失败。
1条答案
按热度按时间zu0ti5jz1#
我对rust不太熟悉,但我知道正确配置TLS服务器(无论哪种语言)需要服务器证书、与证书匹配的密钥以及 * 从服务器证书到客户端机器上的根CA构建信任链所需的所有中间CA a。这些中间CA在代码中没有提供,这就是Python代码无法验证证书的原因。
你需要的可能是这样的东西:
其中
intermediate_cert
是 Let's Encrypt R3 CA的内部表示形式,您可以在此处找到该CA。