Skip to main content

Command Palette

Search for a command to run...

Client Certificate Handling on iOS

Updated
2 min read
Client Certificate Handling on iOS
M

I am a Software Engineer working on open source and enterprise mobile SDKs for iOS and MacOS developers written in Swift. From 🇩🇪 and happily living in 🇺🇸

Client Certificate Authentication, a.k.a. mutual certificate-based authentication, means that the client provides its Client Certificate to the server to prove its identity. This happens as a part of the SSL Handshake (optional).

How Mutal Authentication Works

Users can install digital identities (certificates plus their associated private keys) onto their iOS devices by downloading them from within Safari, by opening them as email attachments, and by installing them with configuration profiles (MDM!).

Once done the SafariViewController or the Safari app can open the page successfully because the certificate is in the Apple keychain access group.

BUT your apps using URLSession or WKWebView will receive an HTTP 400 response because of a missing client certificate ?!?!

That's because ...

Apps can only access keychain items in their own keychain access groups. This means that items in the Apple access group are only available to Apple-provided apps such as Safari or Mail.

The solution is

... you will need to write code to import them. This typically means reading in a PKCS#12-formatted blob and then importing the contents of the blob into the app's keychain using the function SecPKCS12Import documented in Certificate, Key, and Trust Services Reference.

This way, your new keychain items are created with your app's keychain access group.

This statement comes from Apple.

Additional work is needed.

I created an iOS application to demonstrate all this better. Use this app to access https://client.badssl.com/ in various ways

  • URLSession.dataTask
  • WKWebView
  • SFSafariViewController
  • Open link in Safari

The website requires a valid user certificate. Otherwise the server returns HTTP 400.

I added badssl.com-client.p12 (downloaded from badssl.com/download) as a bundle resource for convenience. This allows you to test the successful authentication with a user certificate using URLSession and WKWebView.

Note: If the certificate no longer works (expires Dec 4, 2023), try to download the latest version from badssl.com/download.

The source code of the app is publicly available on GitHub.

J

Finally someone on whole Internet with a clue about my issue. We have a reverse proxy with internal sites that ask for client device authentication that we deploy with Intune. The certificates are working and installed correctly, but they only work with Safari. Because of internal rules, we need to use Edge on iOS for access this sites, but the problem arise. All the browsers except Safari don't send the client certificate, probably as you refer in your article, they don't have access to the keychain where they are installed.

The web server returns always the error: [ssl:error] [pid 399092:tid 139834186258176] SSL Library Error: error:1417C0C7:SSL routines:tls_process_client_certificate:peer did not return a certificate -- No CAs known to server for verification?

More from this blog

Dev blog post potpourri by senior software engineer Marco Eidinger

149 posts

Hello 👋🏻 , I am a Software Engineer working on open source and enterprise mobile SDKs for iOS and MacOS developers written in Swift. From 🇩🇪 and happily living in 🇺🇸