Skip to main content

Obtaining credentials

To use S/MIME, you’ll need a set of “credentials”, which is sometimes called an “identity”. A common type of credentials are usernames and passwords, but S/MIME uses a different type of credentials: certificates and private keys.

S/MIME uses public-key cryptographic algorithms, which involves two related keys with special mathematical properties. The two keys are called a public key and a private key. The certificate (which contains the public key) can be shared with anybody. The private key must be kept secure—do not give it to anyone else.

A certificate needs to be obtained from an issuing authority.

Generate the key pair and Certificate Signing Request

First, generate the public key and private key.

Using the command line

A private key and Certificate Signing Request (CSR) can be generated with:

openssl req -newkey rsa:2048 -sha256 \
  -keyout example.private -out example.csr \
  -subj "/CN=account@example.com"

The req argument generates a CSR. The -newkey rsa:2048 generates a new 2048-bit key pair using the RSA public-key algorithm. The -sha256 uses the SHA-256 algorithm to sign the CSR.

The private key is saved in the -keyout file. For extra security, the private key is encrypted using a passphrase. The private key is not encrypted if the -nodes option is used.

The CSR is saved in the -out file. It contains a copy of the public key that was generated and will be sent to the certificate issuer.

Other options, like -subj, can be used to add other information to the CSR. Most certificate issuers nowdays ignore the other information in the CSR, using the information entered into their Web form used to upload the CSR and request the certificate. Therefore, the values don’t really matter.

To display the information in a CSR:

openssl req -in example.csr -text -noout

Using Keychain Access

A CSR can be also be generated using the Keychain Access application.

  1. From the “Keychain Access” menu, select “Certificate Assistent” > “Request a Certificate from a Certificate Authority”.

  2. Enter the user email address and common name.

  3. Select the checkbox so the request is “Saved to disk”.

  4. Press the “Continue” button.

  5. Select a location to save the .certSigningRequest file.

  6. Close the dialog by pressing the “Done” button.

The public key and private key will both be stored inside your keychain, using the common name as their names.

Obtain a certificate

Certificates signed by a certificate authority

Submit the CSR to a certificate issuer to obtain a certificate. Most certificates issuers provide Web server certificates for TLS or certificates for code signing, but you’ll need to use one that provides S/MIME email certificates.

An example S/MIME certificate provider is DigiCert. Their Website only mentions S/MIME certificates for enterprises and large companies, but they do sell individual S/MIME certificates (in 2021, a certificate with 1 year expiry costs US$45, or 3 years for US$126). Just register for a free account and then contact DigiCert sales with your account number (which found under a drop down menu at the top right corner of the CertCentral portal) to ask them to enable the “Class 1 S/MIME” client certificate product on your account. A “Class 1 S/MIME” certificate only requires proof that you have access to the email address.

The certificate issuer will take the CSR and generate a certificate containing a copy of the public key. That certificate will be signed by their intermediate certificate (sometimes called a Certificate Authority certificate). And that intermediate certificate is usually signed by the issuer’s root certificate. To distinguish it from the other certificates, the certificate containing your public key is sometimes qualified as the “client certificate”.

To display the contents of a certificate:

openssl x509 -in example.crt -text -noout

Creating a self-signed certificate with Keychain Access

A self-signed certificate can be used for testing. But since it is not issued by a trusted certificate issuer, the email signatures it creates will not be trusted by receivers (unless they manually add it to their set of trusted certificates).

Use the Keychain Access application to create a self-signed certificate. From the “Keychain Access” menu choose “Create a Certificate”. Enter a name for the certificate (e.g. the person’s name) and choose “Self-Signed Root” as the identity type and “S/MIME (Email)” as the certificate type. Always select the “Let me override defaults” checkbox, so the certificate’s email address can be entered. The certificate, public key and private key will be stored inside your keychain and is ready for use (i.e. you can skip the PKCS#12 importing steps).

Create a PKCS#12 file

To import the private key and certificate into a keychain file, you will need a PKCS#12 formatted file. If your certificate issuer has already provided a PKCS#12 file, you can use it, otherwise create one from the private key and the other certificates.

First create a file containing the client certificate and all the intermediary certificates:

cat example.crt intermediary-CA.crt > import.crts

Do not include the root certificate in the file, because it should already be in the macOS “System Roots” keychain. Commercial certificate issuers should have their root certificate already trusted by the operating system.

To create a PKCS#12 file with the private key and certificates:

openssl pkcs12 -export -legacy -inkey example.private -in import.crts \
  -name "account@example.com S/MIME exp 20xx" -aes256 -out example.p12

The -legacy option is needed for OpenSSL v3.x and newer. Otherwise, it uses newer algorithms which produces a PKCS#12 file that are not yet supported by macOS/iOS programs.

The private key is specified by the -inkey option, and the certificate chain with the -in option.

The value passed to the -name option is known as a “friendly name”. It is optional, but it will be very useful for identifying the private key when it is inside a keychain. Putting a year or date in it is useful when there are multiple private keys for the same email address (e.g. when the certificate is renewed).

The -aes256 option encrypts the private key in the PKCS#12 file using the AES-256 algorithm.

When prompted, enter the passphrase to decrypt the private key input file. A non-empty passphrase must be provided to encrypt the private key in the PKCS#12 output file (while OpenSSL accepts an empty passphrase, Keychain Access will not).

Optional commands for using the PKCS#12 file

To display information about a PKCS#12 file:

openssl pkcs12 -in example.p12 -info

To extract the client certificate from a PKCS#12 file:

openssl pkcs12 -in example.p12 -clcerts -nokeys -out cert.crt

To extract the private key from a PKCS#12 file:

openssl pkcs12 -in example.p12 -nocerts -nodes -out privkey.private

Warning: the displayed/extracted private key is not encrypted.

File naming convention

For certificates, the “.crt” file extension is commonly used for a single certificate. The “.cer” extension may also be used.

There is no convention for a file containing multiple certificates. The above example uses the “.crts” file extension.

For PKCS#12 files, macOS recognises both “.p12” and “.pkcs12” extensions.

For Certificate Signing Requests, macOS recognises the “.certSigningRequest” file extension, but it is more conventional to use the “.csr” extension.

For private keys, there appears to be no convention on macOS. The above uses the “.private” file extension, because on macOS the “.key” extension is treated as a Keynote file and a “.pvt” extension is treated as a Pivot Stickfigure Animator file.

Example icons
Credential file icons in Finder

See also

External links

DigiCert
A provider of S/MIME certificates.
Actalis
Another provider of S/MIME certificates which has free 1 year S/MIME certificates.