rust 将.pem键转换为.der编译但导致错误

waxmsbnn  于 2022-12-23  发布在  其他
关注(0)|答案(1)|浏览(165)

调用我的基于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的文档:

我在PKEYCERT变量中使用的密钥是certbot生成的.pem密钥,使用以下命令转换为.der
x1米11米1x
openssl 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服务器的密钥),我如何理解这些错误?我尝试了各种其他编码,这些编码与文档相反,都以同样的方式失败。

zu0ti5jz

zu0ti5jz1#

我对rust不太熟悉,但我知道正确配置TLS服务器(无论哪种语言)需要服务器证书、与证书匹配的密钥以及 * 从服务器证书到客户端机器上的根CA构建信任链所需的所有中间CA a。这些中间CA在代码中没有提供,这就是Python代码无法验证证书的原因。
你需要的可能是这样的东西:

ServerConfig::builder()
        ....
        .with_single_cert(vec![cert, intermediate_cert], key)

其中intermediate_certLet's Encrypt R3 CA的内部表示形式,您可以在此处找到该CA。

相关问题