How to run 'dotnet dev-certs https --trust'? How to run 'dotnet dev-certs https --trust'? asp.net asp.net

How to run 'dotnet dev-certs https --trust'?


On Ubuntu the standard mechanism would be:

  • dotnet dev-certs https -v to generate a self-signed cert
  • convert the generated cert in ~/.dotnet/corefx/cryptography/x509stores/my from pfx to pem using openssl pkcs12 -in <certname>.pfx -nokeys -out localhost.crt -nodes
  • copy localhost.crt to /usr/local/share/ca-certificates
  • trust the certificate using sudo update-ca-certificates
  • verify if the cert is copied to /etc/ssl/certs/localhost.pem (extension changes)
  • verify if it's trusted using openssl verify localhost.crt

Unfortunately this does not work:

$ openssl verify localhost.crtCN = localhosterror 20 at 0 depth lookup: unable to get local issuer certificateerror localhost.crt: verification failed
  • due to that it's impossible to have a dotnet client trust the certificate

Workaround: (tested on Openssl 1.1.1c)

  1. manually generate self-signed cert
  2. trust this cert
  3. force your application to use this cert

In detail:

  1. manually generate self-signed cert:

    • create localhost.conf file with the following content:
[req]default_bits       = 2048default_keyfile    = localhost.keydistinguished_name = req_distinguished_namereq_extensions     = req_extx509_extensions    = v3_ca[req_distinguished_name]commonName                  = Common Name (e.g. server FQDN or YOUR name)commonName_default          = localhostcommonName_max              = 64[req_ext]subjectAltName = @alt_names[v3_ca]subjectAltName = @alt_namesbasicConstraints = critical, CA:falsekeyUsage = keyCertSign, cRLSign, digitalSignature,keyEncipherment[alt_names]DNS.1   = localhostDNS.2   = 127.0.0.1
  • generate cert using openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt -config localhost.conf
  • convert cert to pfx using openssl pkcs12 -export -out localhost.pfx -inkey localhost.key -in localhost.crt
  • (optionally) verify cert using openssl verify -CAfile localhost.crt localhost.crt which should yield localhost.crt: OK
  • as it's not trusted yet using openssl verify localhost.crt should fail with
CN = localhosterror 18 at 0 depth lookup: self signed certificateerror localhost.crt: verification failed
  1. trust this cert:

    • copy localhost.crt to /usr/local/share/ca-certificates
    • trust the certificate using sudo update-ca-certificates
    • verify if the cert is copied to /etc/ssl/certs/localhost.pem (extension changes)
    • verifying the cert without the CAfile option should work now
$ openssl verify localhost.crt localhost.crt: OK
  1. force your application to use this cert

    • update your appsettings.json with the following settings:
"Kestrel": {  "Certificates": {    "Default": {      "Path": "localhost.pfx",      "Password": ""    }  }}


In adition to crisvdb answer, I've several information to add and is the continuation of the walktrough. I don't comment because is pretty complex comment this, but before this answer take a look to crisvdb answer first and then return to continue.

  1. You can make your cert in any folder, can be or can't be in the same folder of the app.
  2. Take openssl verify -CAfile localhost.crt localhost.crt as not optional step, mandatory. It will help.
  3. Do not recompile or touch the code meanwhile you are doing this, in order to get first scenario clean.
  4. In some distributions, as Raspbian for Raspberry Pi, CA certificates are located in /etc/ssl/certs as well as /usr/share/ca-certificates/ and in some cases /usr/local/share/certificates.
  5. Do not copy the cert manually to trusted certs, run sudo update-ca-certificates
  6. If you use a password while making the certificate, you should use it in the appsettings.json
  7. If you get this error:

Interop+Crypto+OpenSslCryptographicException: error:2006D002:BIOroutines:BIO_new_file:system lib

Take in consideration that error means "access denied". It can be because you don't have permissions or related.

7b) Could be also that the file is not found, I use the entire path in the config:

 "Path": "/home/user/www/myfolder1/myapp/localhost.pfx",
  1. After that, and if everything works, you could see a 500 error if you are using Apache or Apache2.

If you get the following error in the apache logs of the site:

[ssl:error] [remote ::1:yourport] AH01961: SSL Proxy requested foryoursite.com:443 but not enabled [Hint: SSLProxyEngine] [proxy:error]AH00961: HTTPS: failed to enable ssl support for [::1]:yourport(localhost)

you must set in the VirtualHost the following configuration after SSLEngine On and before your ProxyPass

SSLProxyEngine on
  1. After that, and if everything works, you could see a 500 error if you are using Apache or Apache2.

If you get the following error in the apache logs of the site:

[proxy:error] [client x.x.x.x:port] AH00898: Error during SSLHandshake with remote server returned by /[proxy_http:error] [client x.x.x.x:port] AH01097: pass request body failed to [::1]:port(localhost) from x.x.x.x()

you must set in the VirtualHost the following configuration after SSLProxyEngine on and before your ProxyPass

SSLProxyVerify noneSSLProxyCheckPeerCN offSSLProxyCheckPeerName off


Looks like this is a known issue with dotnet global tools and that specific command is only available for MacOS and Windows. See this issue on github: Issue 6066.

It seems like there may be a work around for Linux users based on this SO post: ASP.Net Core application service only listening to Port 5000 on Ubuntu.