My knowledge about SSL is very basic and I need to generate self-signed SSL certificates for a local server [server.local] so I can use it in a mobile app for SSL pinning.
How do I create a self-signed certificate, following the rules established by Apple below, via openssl x509?
- All TLS server certificates must comply with these new security requirements in iOS 13 and macOS 10.15; connections to TLS servers violating these new requirements will fail and may cause network failures, apps to fail, and websites to not load in Safari:
- Certificates and issuing CAs using RSA keys must use key sizes ≥2048 bits; RSA key sizes <2048 bits are no longer trusted
- Certificates, and issuing CAs, must use a hash algorithm from the SHA2 family in the signature algorithm; SHA1 signed certificates are no longer trusted for TLS
- Certificates must present the DNS name of the server in the
SubjectAltNameextension of the certificate; DNS names in theCommonNameof a certificate are no longer trusted - Certificates issued after July 1, 2019, as indicated in the NotBefore field of the certificate, must follow these guidelines:
- Certificates must contain an
extendedKeyUsage(EKU) extension containing theid-kp-serverAuthOID - Certificates must have a validity period of ≤825 days, as expressed in the NotBefore and NotAfter fields of the certificate.
- Certificates must contain an
I created the certificate via:
openssl genrsa -des3 -out myCA.key 2048
openssl req -x509 -new -nodes -key myCA.key -sha256 -days 825 -out myCA.pemAfter installing it on the server and device, when I try to use this inside iOS, I get error:
SSL hostname does not match name(s) in certificate,
Extended key usage does not match certificate usage, Root is not trusted` 0 1 Answer
Self-signed certificates should never be used, as they have no Chain of Trust and are therefore insecure and pointless; the recommended way is to create a self-signed CA, using that CA to sign the certificate via an openssl.cnf, such as this custom one.
- The
commonName[CN] cannot be an IP or DNS name, since doing so is insecure; I always recommend using theCNto name the cert (e.g.Apache Web Server X,VPN Server 1, etc.) - SAN [
SubjectAltName] profiles can contain:email: email addressURI: Uniform Resource IndicatorDNS: DNS domain name [local or FQDN]ID: Registered ID: Object Identifier [OID]IP: IP addressdirName: Distinguished NameotherName:OID;content[arbitrary data associated with an OID]
(Content value is in standardASN1_generate_nconfformat)
Execute all commands from within the directory that will contain openssl.cnf:
- Download the custom
openssl.cnf: (Linux/Windows)# Linux: wget # Windows: wget - Edit the SAN profiles of the certs to be created: (lines 151 - 244)
- CA: Edit line 170 [
Router.1] to name your CA[ alt_ca_main ] DNS.1 = Router.1 IP.1 = 127.0.0.1[ alt_ca_main ]
alt_: specifies a SAN profile
ca_main: custom name for the SAN profile
(If renaming: update CA V3 profile line 264 [@alt_ca_main])DNS.1:
Names the CA to make it easier when managing multiple CAs/ICAsIP.1:
Some router OSes require the loopback IP to be specified in the master CA
- Client/Server Cert: Edit lines 189 - 193
[ alt_sophos ] IP.1 = 192.168.2.1 IP.2 = 127.0.0.1 DNS.1 = UTM.WRT DNS.2 = your.ddns.com[ alt_sophos ]:
SAN profile name; changesophosonly if wishing to rename
(If renaming: update V3 profile lines 331 [v3_sophos] and 337 [@alt_sophos])IP.1:
Server IP (if accessible via SSH, loopback IP must be specified [IP.2])
(list additional IPs on new lines with chronological listings; e.g.IP.3)DNS.1:
LocalHostname.LocalDomainDNS.2:
DDNS/FQDN
(list additional names on new lines with chronological listings; e.g.DNS.3)
- CA: Edit line 170 [
- Create prerequisite files and directories: (lines 436 - 455)
mkdir crl; echo 01 > crl\crlnumber; echo > index; echo > rand; echo 00 > serialcrlnumber:
serial for the next CRL [Certificate Revocation List] signed (lines 443 - 446)index:
list of all certs created (lines 448 - 451 and 642 - 686)openssl camust be used to maintain theindexautomatically, which I don't cover, as it overcomplicates the process (manually maintain: lines 642 - 686)
rand:
random characters used for certificate/key creation (lines 453 - 455)serial:
serial [hex] of last cert signed, can be any number (lines 438 - 441 and 671 - 681)
- Create CA:
Most can ignore, as vast majority are fine using RSA:# CA key should have a secure passphrase of at least 20 characters, containing: # 2 uppercase, 2 lowercase, 2 numbers, and 2 symbols # Request: openssl req -x509 -new -sha512 -days 3650 -newkey rsa:4096 -keyout 'CA.key.pem' -out 'CA.crt.pem' -config '.\openssl.cnf' -extensions v3_ca # Generate CA CRL Cert: openssl ca -gencrl -keyfile 'CA.key.pem' -cert 'CA.crt.pem' -out 'CA.crl.pem' -config '.\openssl.cnf' # Convert CA CRL Cert to DER CRL: openssl crl -inform PEM -in '.\CA.crl.pem' -outform DER -out '.\CA.crl'
Type of key chosen determines the Key Exchange Algorithms that can be used [below]- It's imperative the CA V3 profile's KUs are not altered (lines 260 - 265)
- (Optional) Create ICA [Intermediate CA]:
Useful if needing multiple CAs to lower risk of any one being compromised
Most can ignore, as vast majority are fine using RSA:# ICA key should have a secure passphrase of at least 20 characters, containing: # 2 uppercase, 2 lowercase, 2 numbers, and 2 symbols # Request: openssl req -out '.\ICA.csr' -new -days 3650 -sha512 -newkey rsa:4096 -keyout 'ICA.key.pem' -config '.\openssl.cnf' -extensions v3_ica_router2 # Sign ICA with CA: openssl x509 -req -sha512 -days 3650 -in '.\ICA.csr' -CA 'CA.crt.pem' -CAkey 'CA.key.pem' -CAserial '.\serial' -out 'ICA.crt.pem' -extfile '.\openssl.cnf' -extensions v3_ica_router2 # Generate ICA CRL Cert: openssl ca -config '.\openssl.cnf' -gencrl -keyfile 'ICA.key.pem' -cert 'ICA.crt.pem' -out '.\ICA.crl.pem' # Convert ICA CRL Cert to DER CRL: openssl crl -inform PEM -in '.\ICA.crl.pem' -outform DER -out '.\ICA.crl' # Concatenate ICA and CA Cert: # Linux: cat './ICA.crt.pem' './CA.crt.pem' > './CA-ICA-Chain.crt.pem' # Windows: cmd /c type '.\ICA.crt.pem' '.\CA.crt.pem' > '.\CA-ICA-Chain.crt.pem'
Type of key chosen determines the Key Exchange Algorithms that can be used [below]- It's imperative the ICA V3 profiles' KUs are not altered (lines 267 - 279)
- ICA V3 profiles contian
pathlen:0(they can sign certs, but not CAs/ICAs); ifpathlenis not specified/number set, it can sign an infinite/specified number of CAs/ICAs
- Create certificates: (if V3 profile was renamed in 2.2, update here)
Most can ignore, as vast majority are fine using RSA:# Server certs: add -nodes to the end of the Request command; else server requires # manually entering encryption passphrase when starting (impractical) # Request: openssl req -out '.\server.csr' -new -days 825 -sha512 -newkey rsa:2048 -keyout '.\server.key.pem' -config '.\openssl.cnf' -extensions v3_sophos -nodes # Sign: # CA only: openssl x509 -req -sha512 -days 825 -in '.\server.csr' -CA '.\CA.crt.pem' -CAkey '.\CA.key.pem' -CAserial '.\serial' -out '.\server.crt.pem' -extfile '.\openssl.cnf' -extensions v3_sophos # ICA: (change to) -CA '.\CA-ICA-Chain.crt.pem' -CAkey '.\ICA.key.pem' # (Optional) Export: # CA only: openssl pkcs12 -export -out '.\server.p12' -inkey '.\server.key.pem' -in '.\server.crt.pem' -certfile 'CA.crt.pem' # ICA: (change to) -certfile 'CA-ICA-Chain.crt.pem' # CA - ICA chain cert must be exported to maintain the Chain of Trust of: Cert → ICA → CA
Type of key chosen determines the Key Exchange Algorithms that can be used [below]
References:
Certificate Verification:
- Certificate:
openssl x509 -text -noout -in 'cert.crt.pem' - Certificate Signing Request [CSR]:
openssl req -text -noout -verify -in 'cert.csr' - Key:
openssl rsa -check -in 'cert.key.pem' - PKCS12 [
.pfx/.p12]:openssl pkcs12 -info -in 'cert.p12'
Hex ⟷ Dec Conversion:
- Linux:
# hex → dec: (returns 10) printf '%d\n' 0x0a # dec → hex: (returns 0a) printf '%x\n' 10 - Windows:
Calculator has programmer mode
index:
# Manually maintain the index file by inputting one cert entry per line in the following format: # 1 2-----------> 3-> 4> 5-----> 6----------------------------------------------------------------------------> V 261231235959Z 0a unknown /C=US/ST=State/L=Locality/O=Org/OU=Unit/CN=Common Name/emailaddress= # 1 Status of Certificate: V # Valid R # Revoked E # Expired # 2 Expiration Date: YYMMDDHHMMSSZ # Date format followed by 'Z' (2026.12.31 @ 23:59:59) # 3 Revocation Date: (empty if not revoked) YYMMDDHHMMSSZ,reason # Valid reasons are: ## keyCompromise ## CACompromise ## affiliationChanged ## superseded ## cessationOfOperation ## certificateHold ## privilegeWithdrawn ## AACompromise # Certain distros error out without a whitespace for 3 # 4 Serial number in hex format: 0a # hex for 10 # 5 Certificate Filename or Literal String unknown # Certificate filename or literal string 'unknown' # 6 Distinguished Name
Key Exchange Algorithms:
RSA:
Encrypts a random value, chosen by the client, via the server public key- Required:
Server public key must be an RSA key
Server certificate must have KUkeyAgreement
- Required:
DH_RSA:
Key exchange occurs via a static Diffie-Hellman key- Required:
CA must be using an RSA signing key
Server public key must be a Diffie-Hellman key
Diffie-Hellman key must have been issued by a CA
- Required:
DH_DSA:
LikeDH_RSA, except the CA used a DSA key in lieu of RSADHE_RSA:
Key exchange occurs via an Ephemeral Diffie-Hellman- Server dynamically generates & signs a DH public key, sending it to the client
- Required:
Server public key must be an RSA key
Server certificate must have KUdigitalSignature
DHE_DSA:
LikeDHE_RSA, except the CA used a DSA key in lieu of RSA
Elliptic-Curve Key Exchange Algorithms:
ECDH_RSA:
LikeDH_RSA, but with elliptic-curves- Required:
Server public key must be an ECDH key
Server certificate must be issued by a CA using an RSA public key
- Required:
ECDH_ECDSA:
LikeECDH_RSA, except the CA used an ECDSA keyECDHE_RSA: Server sends dynamically generated EC Diffie-Hellman key, signing it via it's RSA key- Server public key signs the Ephemeral EC Diffie-Hellman key
ECDHE_ECDSA:
LikeECDHE_RSA, except server public key is an ECDSA key- Equivalent to
DHE_DSS, but with elliptic curves for both the Diffie-Hellman & signature
- Equivalent to