How To Use S/MIME Certificates For Email On Apple Devices
Introduction
A lot of folk use GPG for signing and encrypting emails but GPG is notoriously complex for folk who are not geeks and can often be a pain to use even by seasoned tech folk. On Apple macOS you can use GPG with the standard Mail.app via GPG Suite but note that the Mail integration is paid for and Apple sometimes pull the rug and it takes them a while to get it working again with the latest versions. The 'native' built-in way to sign emails and/or encrypt is via S/MIME certificates, the good thing with this method is the UI will show a cert has been used and it also works with other devices such as iPads and iPhones, with GPG it is impossible to get it working with those devices.
Note that to get a certificate that is trusted you need to buy it the same as any other SSL/TLS certificate, the cost is minimal though, I use SSLTrust for my S/MIME certs and pay £11.03 for a year.
Generate CSR
First create a Certificate Signing Request (CSR), this will be what needs to be submitted to your chosen SSL/TLS vendor.
Rather than using a million openssl
argument flags a bunch of stuff
can be added to a config file, this makes the command simpler but also
makes it easier to do renewals in future. This is what my csr.conf
file looks like:
# Config for generating a CSR with openssl for an S/MIME certificate. # openssl req -newkey rsa:2048 -keyout me_rosstimson_com.key -out me_rosstimson_com.csr -config csr.conf [req] prompt = no distinguished_name = dn req_extensions = ext [dn] C = GB CN = me@rosstimson.com emailAddress = me@rosstimson.com [ext] subjectAltName = email:me@rosstimson.com keyUsage = critical,digitalSignature,keyEncipherment extendedKeyUsage = emailProtection
To generate the CSR using the config file run the command:
openssl req -newkey rsa:2048 \ -keyout me_rosstimson_com.key \ -out me_rosstimson_com.csr \ -config csr.conf
This will output the CSR to provide to the vendor as well as the secret key.
Note: DigiCert - OpenSSL CSR Wizard is handy for helping create the command needed for generating a CSR if you don't wish to us a config file.
Prepare Bundle For Usage
Once the vendor has created the S/MIME certificate it can be downloaded along with the intermediate and root certificates. We need to bundle them all together along with the private key in PKCS#12 (.p12) format.
I have the following files in my working directory now:
.rw-r--r--@ 5.0k rosstimson staff 29 Apr 21:36 bundled.pem .rw-rw-r--@ 1.7k rosstimson staff 30 Apr 06:36 me_rosstimson_com.crt .rw-r--r--@ 443 rosstimson staff 25 Apr 21:32 csr.conf .rw-rw-r--@ 2.0k rosstimson staff 30 Apr 06:36 intermediate-0.crt .rw-r--r--@ 1.1k rosstimson staff 25 Apr 21:14 me_rosstimson_com.csr .rw-------@ 1.9k rosstimson staff 25 Apr 21:14 me_rosstimson_com.key .rw-rw-r--@ 1.3k rosstimson staff 30 Apr 06:36 root-certificate.crt
The me_rosstimson_com.crt
is the issued certificate. To create the
bundle ready for usage with Apple devices use the following command:
/usr/bin/openssl pkcs12 -export -out me_rosstimson_com_bundle.p12 \ -inkey me_rosstimson_com.key \ -in me_rosstimson_com.crt \ -certfile intermediate-0.crt \ -certfile root-certificate.crt \ -passout pass:"SOME_SECRET" Enter pass phrase for me_rosstimson_com.key:
The command will prompt for the passphrase used when the private key
was created during CSR generation. The command would normally ask for
a password for the outputted .p12 bundle too but here the -passout
argument is used as when cut 'n' pasting from my password manager I
was getting the error Can't read Password
, so rather than
painstakingly typing out a long password it is supplied with the
command; weirdly the private key password can be read when pasted in.
Import The Certificate Into Keychain
You can do this via Finder by just double-clicking on the .p12 file or by opening Keychain.app and using the import menu item but it's easier to use the command line:
$ security import me_rosstimson_com_bundle.p12 -k ~/Library/Keychains/login.keychain-db 1 identity imported. 1 certificate imported.
Note: If following these steps to renew a certificate then you should remove the existing, soon to expire, certificate from Keychain.app before trying to import the new one.
Once successfully imported you should be able to see it within Keychain.app within 'login -> certificates', this is what mine looks like:
Testing
If the certificate is in Keychain.app and showing as valid then try sending a message to yourself, you should see a signing option like this when composing an email:
When you receive the email you should be able to see that the email is signed like the screenshot in the introduction and if you click on it you can double check the validity and expiry of the certificate:
iPad and iPhone
If you use iCloud and trust it to store the .p12 which of course includes the private key then place it somewhere in there and then access it from the Files.app from iOS or iPadOS. By tapping on the .p12 file the device will prompt about installing it. The alternative is to email the p12 file to yourself and then access it from the mail client on any mobile devices.
Once installed the cert weirdly 'lives' within Settings -> General -> VPN & Device Management, again if renewing you can delete a soon to expire cert from here too. This is what mine looked like, you can then click onto the 'Configuration Profile' to check the details of the cert.
Issues
I have the latest version of OpenSSL installed via Homebrew on my mac
and when generating the CSR and creating the p12 bundle I was using
the Homebrew installed version of the openssl
command as they come
first in my $PATH
. However, when it then came to installing the p12
bundle into Keychain.app I was getting all sorts of misleading errors
about it being invalid or about the passphrase being wrong. What was
actually wrong is a mismatch between the versions of OpenSSL, this is
why in the .p12 creation command I've used the full path to the macOS
system version /usr/bin/openssl
, when you create the .p12 with that
one then it will install into Keychain.app fine. This confused me and
had me banging my head against the wall for over an hour, hopefully
this note saves you some time and confusion.