One self-signed cert to rule them all? Chrome, Android, and iOS One self-signed cert to rule them all? Chrome, Android, and iOS google-chrome google-chrome

One self-signed cert to rule them all? Chrome, Android, and iOS


This answer has been updated (and simplified) to be compatible with iOS 13 and Android 8. Credit now goes to https://discussions.apple.com/thread/250666160 answer by user:fixitnowyes on October 6, 2019.

Just one openssl command works to create a self-signed certificate that works in Chrome, Android, and iOS:

openssl req -config openssl.cnf -new -x509 -days 825 -out ca.crt

This outputs both ca.crt and ca.key. Note that 825 days is the maximum duration allowed by iOS 13+, and it must be specified in the openssl command. The days setting in openssl.cnf does not do anything that I can tell.

Check information about the certificate with:

openssl x509 -in ca.crt -text -noout

Contents of openssl.cnf:

[ req ]default_bits        = 2048default_keyfile     = ca.keydefault_md          = sha256default_days        = 825encrypt_key         = nodistinguished_name  = subjectreq_extensions      = req_extx509_extensions     = x509_extstring_mask         = utf8onlyprompt              = no# The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).#   Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.[ subject ]countryName                 = USstateOrProvinceName         = OklahomalocalityName                = StillwaterorganizationName            = My CompanyOU                          = Engineering# Use a friendly name here because it's presented to the user. The server's DNS#   names are placed in Subject Alternate Names. Plus, DNS names here is deprecated#   by both IETF and CA/Browser Forums. If you place a DNS name here, then you#   must include the DNS name in the SAN too (otherwise, Chrome and others that#   strictly follow the CA/Browser Baseline Requirements will fail).commonName              = test.comemailAddress            = me@home.com# Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...[ x509_ext ]subjectKeyIdentifier      = hashauthorityKeyIdentifier    = keyid:always,issuer# You only need digitalSignature below. *If* you don't allow#   RSA Key transport (i.e., you use ephemeral cipher suites), then#   omit keyEncipherment because that's key transport.basicConstraints        = critical, CA:TRUEkeyUsage            = critical, digitalSignature, keyEncipherment, cRLSign, keyCertSignsubjectAltName          = DNS:test.comextendedKeyUsage = serverAuth# RFC 5280, Section 4.2.1.12 makes EKU optional#   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused#   In either case, you probably only need serverAuth.extendedKeyUsage    = TLS Web Server Authentication# Section req_ext is used when generating a certificate signing request. I.e., openssl req ...[ req_ext ]subjectKeyIdentifier        = hashbasicConstraints        = CA:FALSEkeyUsage            = digitalSignature, keyEnciphermentsubjectAltName          = DNS:test.comnsComment           = "OpenSSL Generated Certificate"# RFC 5280, Section 4.2.1.12 makes EKU optional#   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused#   In either case, you probably only need serverAuth.# extendedKeyUsage    = serverAuth, clientAuth# [ alternate_names ]# DNS.1       = example.com# DNS.2       = www.example.com# DNS.3       = mail.example.com# DNS.4       = ftp.example.com# Add these if you need them. But usually you don't want them or#   need them in production. You may need them for development.# DNS.5       = localhost# DNS.6       = localhost.localdomain# DNS.7       = 127.0.0.1# IPv6 localhost# DNS.8     = ::1

After creating the certificates...

Server installation:

  1. Install ca.crt and ca.key in your server.
  2. Restart server.

Chrome / Safari installation:

  1. Add ca.crt to your Mac's KeyChain Access in the System keychain (or PC equivalent).
  2. Set it to "Always Trust" (in Mac) so that it works in Chrome and Safari.

iOS installation:

  1. Drag ca.crt to the simulator. At least this works in Xcode 12. Note that there is no confirmation that anything happened.
  2. There should be no need to go to Settings / General / About / Certificate Trust Settings and enable it. It should be already enabled.

If the above doesn't work, you may be able to find out why by emailing the ca.crt file to yourself, logging into the Mail app in the simulator, then opening it from there.

Android installation:

  1. Email ca.crt to your Gmail account, then log into Gmail in yourAndroid simulator and tap to install it.
  2. It should appear in the "USER" tab under Settings / Lock screen & security / Encryption & credentials / Trusted credentials.