Search code examples
vue.jsflaskaxiosopensslself-signed-certificate

Invalid certificate authority error when not working in localhost


I am trying to implement HTTPS on a development website for a demo. My Front end is a VueJS application and my Back end is a Flask application using Python.

To implement HTTPS on my website I did as following:

Generated self signed certificate:

Private key is a RSA 2048 encrypted key called 'private.key'.

Generate a csr certificate with certificate.txt.

openssl req -new -config certificate.txt -key private.key -out certificate.csr 

Generate the final certificate with certificate.csr

openssl x509 -signkey private.key -in certificate.csr -req -days 365 -out certificate.crt

With certificate.txt as following:

[ req ]
prompt = no
distinguished_name = dn
req_extensions = req_ext

[ dn ]
CN = test.domain.en
emailAddress = [email protected]
O = Company
OU = test
L = UK
ST = UK
C = UK

[ req_ext ]
subjectAltName = DNS: localhost, DNS: test.domain.en, IP: X.X.X.X:XXXX'ip of my vm'

Front end (VueJS configuration):

Adding in vue.config.js the link to the certificate and the private key

const fs = require('fs');

module.exports = {
  devServer: {
    https: {
        key: fs.readFileSync('src/assets/certificate/private.key'),
        cert: fs.readFileSync('src/assets/certificate/certificate.crt'),
    },
    public: 'https://protected.deloitte.lu:8080/',
    disableHostCheck: true,
  },
};

Adding rejectUnauthorized parameter in an httpsAgent in axios when making a POST request

const httpsAgent = new https.Agent({  
    rejectUnauthorized: false
});

axios.post(payload, formData, {headers: headers, httpsAgent: httpsAgent})

Back end (Flask configuration in Python)

Adding certificate and key in a ssl context when app is running

if __name__ == '__main__':
    context=('./certs/certificate_cloud.crt','./certs/private.key')
    app.run(host='0.0.0.0', port=5008, debug=False, ssl_context=context)
  • Web browser (Chrome configuration)

Enabled : chrome://flags/#allow-insecure-localhost

Installed certificate.crt in 'Trusted Root Certification Authorities'

Results:

Frontend: https://localhost:8080/

Backend: https://X.X.X.X:5008/

When the back end is hosted and running on localhost, the post request is working well and the protocol is HTTPS as requested.

However, when I migrate the flask application on an AWS virtual machine I get this error:

POST https://XXX.XXX.XXX.XXX:XXXX/path/to/function/ net::ERR_CERT_AUTHORITY_INVALID

What I already tried:

Replace ssl_context=context with ssl_context='adhoc'

Generate several certificate with different domain name, and config the ip with this domain name.

Additional question:

Is it possible to remove the 'Not secure' icon on Chrome with a self signed certificate generate with openssl?

enter image description here


Solution

  • I have just noticed that I never published the solution to this question. You can find below all steps to create a self signed certificate recognized by your local laptop browser (Google Chrome). Hope it would be helpful for some people:

    1. Open a command promt

    2. Install OpenSSL command lines on your laptop by Downloading Git for Windows here: https://gitforwindows.org/

    3. Once installed, search for "Git bash" in Windows search bar and open it

    4. If it is well installed, by typing openssl version, you should see in the command prompt opened: OpenSSL <your.current.version> <date_of_today>

    5. Create a private.key with this command line: openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout private.key -out certificate.crt (Type Enter for each parameter, keep the "private.key" and delete "certificate.crt")

    6. Create a "certificate.txt" file with the following text:

    
    [ req ]
    
    prompt = no
    
    distinguished_name = dn
    
    x509_extensions = req_ext
    
     
    
    [ dn ]
    
    CN = <DOMAIN-NAME-OF-YOUR-WEBSITE>
    
    emailAddress = [email protected]
    
    O = <YOUR-COMPANY-NAME>
    
    OU = <YOUR-COMPANY-DEPARTMENT-NAME>
    
    L = <YOUR-COUNTRY>
    
    ST = <YOUR-COUNTRY>
    
    C = <YOUR-COUNTRY-CODE>
    
     
    
    [ req_ext ]
    
    subjectAltName = @alt_names
    
     
    
    [ alt_names ]
    
    DNS.1 = localhost
    
    DNS.2 = <DOMAIN-NAME-OF-YOUR-WEBSITE>
    
    DNS.3 = <ANOTHER-DOMAIN-NAME-OF-YOUR-WEBSITE>
    
    
    1. Create a certificate "certificate_final.crt" with the command line: openssl req -new -x509 -key private.key -days 365 -out certificate_final.crt -config certificate.txt (The certificate is valid for 365 days)

    2. Open this "certificate_final.crt" file

    3. Click on "Install Certificate"

    4. Select "Current User"

    5. Select "Place all certificates in the following store" and "Browse"

    6. Select "Trusted Root Certification Authorities"

    7. Click on "Finish"

    8. Open "Google Chrome"

    9. In the top search bar, enter chrome://flags/#allow-insecure-localhost. It will enable Chrome to recognize your self signed certificate. Unselect this option at the end of your demonstration for browsing web with real valid certificate

    10. Adapt paths to "private.key" and "certificate_final.crt" in the "vue.config.js" file

    11. Run the npm run serve. If everything went well you should see "Network: https://DOMAIN-NAME-OF-YOUR-WEBSITE:8080/" in the terminal meaning that you are using a custom domain name in HTTPS.