我使用 Rust 的 quinn 库写一个简单的 QUIC 连接,本地开发使用自签名证书一直报 Error:
Error: ConnectionClosed(ConnectionClose { error_code: Code::crypto(30), frame_type: None, reason: b"invalid peer certificate: UnknownIssuer" })
error: process didn't exit successfully: `C:\Projects\friends\target\debug\server.exe` (exit code: 1)
Rust version: 1.78 stable OS: Windows 11 OpenSSL: 3.0.11 19
折腾了很久不知道为什么。下面是代码和自签名的细节:
// Server code
use std::{fs, sync::Arc};
use quinn::crypto::rustls::QuicServerConfig;
use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
pub const ALPN_QUIC_HTTP: &[&[u8]] = &[b"hq-29"];
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenv::dotenv()?;
env_logger::init();
rustls::crypto::ring::default_provider()
.install_default()
.expect("Failed to install rustls crypto provider");
let cert = fs::read("C:/Projects/certificates/certificate.der")?;
let key = fs::read("C:/Projects/certificates/private_key.der")?;
let cert = CertificateDer::from(cert);
let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::try_from(key)?);
let mut server_config = rustls::ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(vec![cert], key)?;
server_config.alpn_protocols = ALPN_QUIC_HTTP.iter().map(|&x| x.into()).collect();
let server_config =
quinn::ServerConfig::with_crypto(Arc::new(QuicServerConfig::try_from(server_config)?));
let endpoint = quinn::Endpoint::server(server_config, "127.0.0.1:8898".parse()?)?;
let mut b = [0u8; 1024];
while let Some(conn) = endpoint.accept().await {
let (mut send, mut recv) = conn.await?.open_bi().await?;
while let Ok(_) = recv.read(&mut b).await {
send.write_all(&mut b).await?;
}
}
Ok(())
}
// Client
use std::fs;
use std::sync::Arc;
use quinn::crypto::rustls::QuicClientConfig;
use rustls::pki_types::CertificateDer;
pub const ALPN_QUIC_HTTP: &[&[u8]] = &[b"hq-29"];
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenv::dotenv()?;
env_logger::init();
rustls::crypto::ring::default_provider()
.install_default()
.expect("Failed to install rustls crypto provider");
let mut roots = rustls::RootCertStore::empty();
roots.add(CertificateDer::from(fs::read(
"C:/Projects/certificates/certificate.der",
)?))?;
let mut client_crypto = rustls::ClientConfig::builder()
.with_root_certificates(roots)
.with_no_client_auth();
client_crypto.alpn_protocols = ALPN_QUIC_HTTP.iter().map(|&x| x.into()).collect();
let client_config =
quinn::ClientConfig::new(Arc::new(QuicClientConfig::try_from(client_crypto)?));
let mut endpoint = quinn::Endpoint::client("0.0.0.0:0".parse()?)?;
endpoint.set_default_client_config(client_config);
let conn = endpoint
.connect("127.0.0.1:8898".parse()?, "localhost")?
.await?;
Ok(())
}
代码非常简单,重点在使用证书的那几行:
let cert = fs::read("C:/Projects/certificates/certificate.der")?;
let key = fs::read("C:/Projects/certificates/private_key.der")?;
roots.add(CertificateDer::from(fs::read(
"C:/Projects/certificates/certificate.der",
)?))?;
使用 openssl 生成证书的步骤按照这篇博客来:How to Create Self-Signed Certificates using OpenSSL
openssl req -x509 -sha256 -days 356 -nodes -newkey rsa:2048 -subj "/CN=Localhost/C=US/L=San Fransisco" -keyout rootCA.key -out rootCA.crt
openssl genrsa -out server_key.pem 2048
添加下面内容到 csr.conf:
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
C = US
ST = California
L = San Fransisco
O = MLopsHub
OU = MlopsHub Dev
CN = Localhost
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = localhost
IP.1 = 127.0.0.1
接着
openssl req -new -key server_key.pem -out server.csr -config csr.conf
添加下面内容到 cert.conf:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
接着
openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server_crt.pem -days 365 -sha256 -extfile cert.conf
将 server_key.pem 转为 private_key.der, 将 server_cert.pem 转为 certificate.der
openssl pkcs8 -topk8 -inform PEM -outform DER -in server_key.pem -out private_key.der -nocrypt
openssl x509 -outform der -in server_cert.pem -out certificate.der
我有将根证书添加信任:
找了很多方法一直不行,求教大佬有没有什么注意
1
cwaken 211 天前 via iPhone
跟浏览器启动配置有关
|
2
cwaken 211 天前 via iPhone
要忽略证书,具体看 zlmdiakit 中 is 关于 http3 提问
|