Do I have to get a valid SSL certificate to make WebTranport server examples work?

1.1k views Asked by At

I tried several WebTranport server examples, but failed to establish a webtransport connection with Chrome 111.

Server examples:

Clients:

The error was either

net::ERR_CONNECTION_RESET.
WebTransportError: Opening handshake failed.

or

net::ERR_QUIC_PROTOCOL_ERROR.QUIC_TLS_CERTIFICATE_UNKNOWN (TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown).
WebTransportError: Opening handshake failed.

To make self-signed SSL certificate working, I tried using Chrome command line args

--user-data-dir=chromequicdata --origin-to-force-quic-on=localhost:4433 --ignore-certificate-errors-spki-list=Gi/HIwdiMcPZo2KBjnstF5kQdLI5bPrYJ8i3Vi6Ybck=

or passing server certificate hash as WebTransport constructor options

  new WebTransport(url, {
    serverCertificateHashes: [
      {algortithm: 'sha-256', value: decodeBase64('Gi/HIwdiMcPZo2KBjnstF5kQdLI5bPrYJ8i3Vi6Ybck=')}
    ]
  });

Do I have to get a valid SSL certificate to make these server examples working?

2

There are 2 answers

0
1majom On

For me the steps that are described in the third server example's comments that you provided worked with Chrome 114 running the client example. They were:

Here are step-by-step instructions on how to do that:

  1. Generate a certificate and a private key: openssl req -newkey rsa:2048 -nodes -keyout certificate.key
    -x509 -out certificate.pem -subj '/CN=Test Certificate'
    -addext "subjectAltName = DNS:localhost"

  2. Compute the fingerprint of the certificate: openssl x509 -pubkey -noout -in certificate.pem | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | base64

    The result should be a base64-encoded blob that looks like this: "Gi/HIwdiMcPZo2KBjnstF5kQdLI5bPrYJ8i3Vi6Ybck="

  3. Pass a flag to Chromium indicating what host and port should be allowed to use the self-signed certificate. For instance, if the host is localhost, and the port is 4433, the flag would be: --origin-to-force-quic-on=localhost:4433

  4. Pass a flag to Chromium indicating which certificate needs to be trusted. For the example above, that flag would be: --ignore-certificate-errors-spki-list=Gi/HIwdiMcPZo2KBjnstF5kQdLI5bPrYJ8i3Vi6Ybck=

Problems I ran into:

  • not using the correct fingerprint at the ignore-certificate-errors-spki-list flag or the correct cert file if i had many in one folder or the correct port number on the client's side
  • using the wrong tag at the cert and key file generation. Because if you want to use this method with a simple IP address, not a hostname, you should use:
    • -addext "subjectAltName = IP.1:..."
  • using an older version of Chrome was also a problem, so you should try to update to 114

These are really general solutions, but they might help you.

0
kixelated On

It's not well documented, but serverCertificateHashes only works for EDCSA certificates valid for <14 days.

Here's how you generate a valid certificate.