There is **nothing fundamentally wrong** with the approach, provided the device’s **private key never leaves the device**. The main complication is that the phone—not the BLE device—is establishing the MQTT/TLS connection.

## The key distinction

The certificate itself is public. Authentication occurs because the client proves possession of the corresponding **private key** by signing part of the TLS handshake. In TLS 1.3, this happens in the `CertificateVerify` step. ([IETF Datatracker][1])

Therefore, simply reading the certificate over BLE and giving it to the phone is insufficient. You need one of these architectures.

### 1. Device acts as a remote TLS signer

The phone performs the MQTT/TLS connection but delegates private-key operations to the BLE device:

```text
MQTT broker
    ↕ TLS
Phone MQTT/TLS client
    ↕ BLE signing request
Embedded device/private key
```

During the TLS handshake:

1. Phone sends the device certificate.
2. TLS library generates the `CertificateVerify` data.
3. Phone sends the digest/signing request over BLE.
4. Device signs it using its private key.
5. Device returns only the signature.
6. Phone completes mutual TLS.

This is cryptographically valid and is similar to using a secure element, smart card, TPM, or hardware-backed keystore. Hardware-backed key systems are specifically designed so applications can use a key without extracting it. ([Android Open Source Project][2])

The difficulty is implementation: your Android/iOS MQTT and TLS libraries must support an **external or asynchronous private-key signer**. Many high-level MQTT libraries expect a conventional `PrivateKey` object and do not readily support a BLE-backed signing operation.

### 2. Device signs an application-level authentication challenge

This is usually easier and often cleaner:

```text
Phone → server: Request device-authentication challenge
Server → phone: Random nonce
Phone → BLE device: Sign nonce + context
Device → phone: Signature
Phone → server: Certificate + signature
Server → phone: Short-lived MQTT credential
Phone → MQTT broker: Connect using short-lived credential
```

The short-lived MQTT credential could be:

* A JWT or similar access token
* A temporary username/password
* A temporary MQTT client certificate
* A session credential issued by your backend

I would generally favor this architecture. It lets your backend authenticate the device certificate while the phone uses an ordinary MQTT client library.

Include at least this in the signed data:

```text
protocol_version
device_serial_number
server_nonce
intended_server/audience
timestamp or expiration
requested permissions
phone/app session identifier
```

That prevents the signature from being reused for another server, session, or purpose.

## Principal security concerns

### Do not export the private key

Sending both the certificate and private key to the phone eliminates much of the value of provisioning a unique device credential. A compromised or rooted phone could copy the identity permanently.

Only send signatures from the device.

### Secure the BLE connection

BLE should use authenticated LE Secure Connections, preferably Numeric Comparison, Passkey Entry, or an equivalent product-specific enrollment process. “Just Works” pairing encrypts traffic but does not provide meaningful protection against an active man-in-the-middle during pairing. ([Nordic Developer Academy][3])

For stronger protection, add application-layer security and mutual device/app authentication rather than relying solely on BLE pairing.

### Avoid creating an unrestricted signing oracle

Do not expose a generic BLE command such as:

```text
SIGN arbitrary_bytes
```

A malicious phone application could use the device to sign unrelated material.

Instead expose a narrowly scoped operation:

```text
AUTHENTICATE_MQTT(challenge, broker_id, expiration)
```

The firmware should:

* Validate the request format
* Require an approved broker or backend identifier
* Apply a domain-separation prefix such as `MYPRODUCT-MQTT-AUTH-V1`
* Reject stale challenges
* Rate-limit attempts
* Optionally require that the phone was previously provisioned or bonded

### Broker authorization remains necessary

A valid certificate should identify the device, but it should not automatically grant access to every MQTT topic. Use broker ACLs tied to the authenticated device identity, for example:

```text
devices/DEVICE123/telemetry      publish
devices/DEVICE123/commands       subscribe
```

MQTT itself recommends using authentication, authorization, and secure communication mechanisms for sensitive systems. ([OASIS Open][4])

## My recommendation

For a phone acting as a passive BLE-to-cloud data ferry, I would use:

```text
Permanent private key:      embedded device only
Device certificate:         embedded device, readable by phone
Device authentication:      signed server challenge over BLE
Phone MQTT credential:      short-lived token or temporary certificate
MQTT authorization:         device-specific topic ACL
BLE protection:             authenticated pairing plus app-level binding
```

That preserves the device’s permanent identity, works with normal phone MQTT libraries, supports credential expiration and revocation, and prevents the permanent private key from ever reaching the phone.

Direct BLE-backed TLS signing is also sound, but it is substantially harder to integrate and may tie you to a particular TLS/MQTT implementation.

[1]: https://datatracker.ietf.org/doc/html/rfc8446?utm_source=chatgpt.com "The Transport Layer Security (TLS) Protocol Version 1.3"
[2]: https://source.android.com/docs/security/features/keystore?utm_source=chatgpt.com "Hardware-backed Keystore"
[3]: https://academy.nordicsemi.com/courses/bluetooth-low-energy-fundamentals/lessons/lesson-5-bluetooth-le-security-fundamentals/topic/security-modes/?utm_source=chatgpt.com "Security modes - Nordic Developer Academy"
[4]: https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html?utm_source=chatgpt.com "MQTT Version 5.0 | OASIS Standard"
