Qburst Logo
Industries
Solutions
Services
Innovation & Insights
Company
Industries
Solutions
Services
Innovation & Insights
Company
Connecting iOS App to Local Devices That Use Self-Signed Certificates
  1. Innovation & Insights
  2. Blog
|
Application SecurityMobile

Connecting iOS App to Local Devices That Use Self-Signed Certificates

Sneha Jose
Sneha Jose

Latest Posts

  • What Spreadsheets Taught me About the Future of Agentic AI

  • The GCC Evolution: Navigating Strategy and Scale in the AI Era

  • How We Reduced Agent Onboarding Cycles for an Insurance Carrier

  • The Agentic Inbox: How We Solved “Last Mile” of Operational Automation

  • From Scrum to SAFe: Scaling Agile for Complex Teams and Business Agility

In one of our projects, we had to establish TLS communication between an iOS app and an accessory device on a local network that used a self-signed certificate. However, every attempt resulted in SSL errors, and we had to find a way to overcome these challenges. Here’s how we did it.

There are plenty of online resources that teach you how to support TLS communication in iOS apps. Transport Layer Security (TLS) is a security protocol that encrypts data and authenticates server and client devices when they communicate over the internet (The term SSL, which refers to its predecessor Secure Sockets Layer, is still frequently used to refer to a TLS connection. In many instances, both “SSL” and “SSL/TLS” are referred to as TLS protocol and TLS certificates.)

The difficulty arises when you have to establish a TLS connection for the communication between accessory devices on a local network and an iOS app, as it happened in our case.

The iOS device in question connects to a camera hotspot and communication occurs over Wi-Fi using URLSession. The camera operated on a local network and used a self-signed certificate rather than one from a trusted certificate authority. It also lacked a stable DNS name. Although the accessory device implemented TLS/SSL certificates and private keys, every attempt to establish a connection failed with an SSL error.

Apple’s Guidelines and Real-World Constraints

Since the device had a self-signed certificate to support TLS, trust wouldn’t be established automatically in the iOS app. Moreover, Apple explicitly discourages self-signed certificates outside of testing scenarios because they lack validation from trusted Certificate Authorities, making them vulnerable to security risks like man-in-the-middle attacks. However, we had no alternative but to proceed with the self-signed certificate. 

To establish a TLS connection, we decided to implement SSL pinning within the iOS app. At first, we tried using TrustKit, a widely used library for SSL pinning. But that turned out to be a dead end. The camera was on the local network; it lacked both a static IP address and a static DNS. To work with TrustKit, a static DNS was required.

We trawled the internet for a solution but couldn’t find any official documentation from Apple to handle this situation. We had to think creatively to overcome the challenge.

A Case for Thinking Outside the Box

After experimenting with different solutions, we finally decided to embed the camera’s public certificate within the iOS app. During the SSL handshake, the app validated the server’s leaf certificate against the embedded certificate, thus establishing trust without relying on a certificate authority. This solved our problem! We successfully enabled TLS communication with the accessory device and got rid of SSL errors.

But there was a catch—our method wasn’t Apple-approved. We knew a custom solution could mean compatibility issues or App Store submission hurdles.

Bringing the Issue to Apple’s Attention

We turned to the Apple developer forum for help. We shared our problem and the technical details of our solution and highlighted the necessity of a workaround mechanism for supporting TLS using self-signed certificates in local network scenarios.

Apple reviewed our case and acknowledged the need for a formalized solution. Since embedding the certificate only works if all instances of the accessory use the same self-signed digital identity, Apple suggested persisting the client certificate upon the initial connection and checking that the accessory uses the same certificate in subsequent connections. Apple called this the SSH approach. By adopting this SSH-like behavior, developers can manage trust with self-signed certificates even when the accessory firmware doesn’t provide robust certificate management.

This guideline, along with two other approaches, is documented in their official resources and serves as a vital reference for iOS developers facing similar challenges.

How to Implement the SSH Approach

To implement the SSH approach, you must disable the App Transport Security for local networking by setting the NSAllowsLocalNetworking property. By doing so, you can allow local connections without completely disabling ATS for all network traffic in the app. 

Then you can override the https self-evaluation as shown below: 

1  //1
2    var expectedServerCertificate: SecCertificate? = nil
3    //2
4    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge) async -> (URLSession.AuthChallengeDisposition, URLCredential?) {
5        switch challenge.protectionSpace.authenticationMethod {
6        //3
7        case NSURLAuthenticationMethodServerTrust:
8            guard let trust = challenge.protectionSpace.serverTrust, shouldAllowHTTPSConnection(trust: trust) else {
9                return (.cancelAuthenticationChallenge, nil)
10            }
11            let credential = URLCredential(trust: trust)
12            return (.useCredential, credential)
13        default:
14            return (.performDefaultHandling, nil)
15        }
16    }
17    
18    //4
19    func shouldAllowHTTPSConnection(trust: SecTrust) -> Bool {
20        guard
21            let chain = SecTrustCopyCertificateChain(trust) as? [SecCertificate],
22            let actualCertificate = chain.first
23        else {
24            return false
25        }
26        guard let expected = expectedServerCertificate else {
27            //Case A
28            expectedServerCertificate = actualCertificate
29            return true
30        }
31        //Case B
32        return CFEqual(expected, actualCertificate)
33    }
34
  1. Here, we are saving the server certificate during the initial connection in the variable expectedServerCertificate. In a real-world app, you can persist this value to ensure the same logic applies when the app is launched again.
  2. The URLSessionDelegate method URLSession:didReceiveChallenge:completionHandler:  is overridden to handle the authentication challenge.
  3. The method NSURLAuthenticationMethodServerTrust only handles HTTPS server trust challenges; For all other cases, it defaults to .performDefaultHandling.
  4. The method shouldAllowHTTPSConnection(trust:) checks if the connection should proceed. Case A: If the app is connecting to the server for the first time, the connection is allowed by default. Case B: If the app has connected before, the method verifies that the certificate has not changed.

Security Challenges of the SSH Approach

One major risk of this method is that an attacker can intercept the initial connection and supply a malicious certificate that gets pinned. To mitigate this risk, additional security measures should be implemented. Some of these include: 

  • Serial Number Verification: If the accessory has a unique serial number, the app can prompt the user to manually enter or scan it via a QR code. This serial number can then be cross-checked with the one in the certificate.
  • User Confirmation: If the accessory has a display, show a UI prompt requiring the user to verify a security code displayed on both the app and the accessory.

These help ensure that the initial connection is made with a legitimate device rather than an attacker, significantly lowering the risk of man-in-the-middle attacks. But they do not provide complete protection. Developers implementing this approach must be aware of the associated risks. 

To securely communicate with a local device, it’s best to create a custom certificate authority (CA) to issue certificates, install the certificate and private keys on the device, and have the app verify the accessory’s certificate against the CA to ensure trusted communication. 

 

 

Latest Posts

  • What Spreadsheets Taught me About the Future of Agentic AI

  • The GCC Evolution: Navigating Strategy and Scale in the AI Era

  • How We Reduced Agent Onboarding Cycles for an Insurance Carrier

  • The Agentic Inbox: How We Solved “Last Mile” of Operational Automation

  • From Scrum to SAFe: Scaling Agile for Complex Teams and Business Agility

Recognized for Growth. Trusted for Impact.

Deloitte Technology Fast 50 India, Winner 2024

Deloitte Fast 50 India, Winner 2024

Dun & Bradstreet

Leading Mid-Corporates of India, 2024

RecognitionImage

Major Contender, QE Specialist Services


Qburst LogoISO
socialLogo
socialLogo
socialLogo
socialLogo
Industries
RetailRealtyHigh-TechHealthcareManufacturing
Solutions
Digital ExperienceIntelligent EnterpriseProduct EngineeringManaged AgentsModernization
Services
Experience DesignDigital EngineeringDigital PlatformsData Engineering & AnalyticsApplied AICloudQuality EngineeringGlobal Capability CentersDigital Marketing
Innovation & Insights
BlogCase StudiesWhitepapersBrochures
Company
LeadershipClientsPartnersCorporate ResponsibilityNews & MediaCareersOur LocationsGrowth Referral
  • Industries
  • Solutions
  • Services
  • Innovation & Insights
  • Company

© QBurst 2026. All Rights Reserved.

Privacy Policy

Cookies & Management

Certifications