Generating Per-Device Keys at Manufacturing
Per-device keys are the right design, but they are only as good as the process that creates them. Generate them carelessly and you reintroduce the very shared-secret problem you were trying to avoid. The safest provisioning assumes the factory itself might be careless or hostile, and arranges things so it never touches a usable secret.
The Process Matters as Much as the Design
Deciding to use per-device keys is the easy part. The hard part is the provisioning process, the sequence of steps at manufacturing that actually creates, certifies, and installs those keys. A flawed process can undo the whole benefit, leaving you with the operational cost of unique keys and the security of a shared one.
The recurring theme of good provisioning is minimizing trust, and assuming the line itself might be careless or hostile, because it often runs at a contractor you do not fully control. Every system that handles a private key, every operator who can read one, and every database that stores one is a place the fleet’s security can leak. The strongest designs are the ones where the fewest parties ever touch a usable secret, ideally none but the device itself.
The Safe Provisioning Flow
The shape that achieves this is simple: the secret is born inside the device and never leaves, and everything the factory handles after that is a public key or a certificate, neither of which is secret.
At no point in that flow does a private key exist off the device, so a breach of the factory, or a dishonest operator, yields public keys and certificates, not the secrets that protect the fleet. Each step below fills in how that holds in practice.
Generate on the Device
The strongest approach has each unit generate its own key pair internally, inside its secure element or crypto hardware, and export only the public key for certification, so the private key never exists anywhere else, not even on the line.
# trigger on-device keygen; the private key never leaves the chip
provision_tool --generate --slot 0 --serial $(read_device_serial)device 340A91F2: generated P-256 keypair in slot 0 exported public key only; private key sealed in secure element
This removes the single most dangerous artifact, a central store of every device’s secret, from the process entirely. There is no file, no database, and no server that holds the private keys, because each one was born inside its device and never came out.
The Two Servers Not to Trust
Two convenient shortcuts reintroduce exactly the single-point-of-failure you were avoiding. The first is generating keys on a factory server and injecting them: that server becomes a single point holding every device’s private key, and a breach, or the wrong operator near it, exposes the whole fleet at once. If a generation server is truly unavoidable, back it with a hardware security module so keys never appear in bulk plaintext, restrict and audit access tightly, and never let it accumulate a readable archive.
The second is the certificate authority that signs device identities, the trust anchor for the entire fleet, whose private key is the most valuable secret in the system: if it leaks, an attacker can mint identities your backends will trust. A common and serious mistake is keeping the CA key on the same factory server that runs provisioning. It should be separated, hardware-protected, kept offline where practical, and used through a controlled signing service, not sitting in a file next to the provisioning script.
Certify the Public Key
After generation, the device’s public key is signed by your certificate authority, giving each unit a verifiable identity tied to your trust anchor. That certificate is what every later authentication and revocation decision references, and it is safe to handle because it contains no secret.
# sign the device's public key with the product CA to mint its identity cert
openssl x509 -req -in device_0.csr -CA product_ca.crt -CAkey product_ca.key \
-days 3650 -out device_0.crtSignature ok subject=CN=device-340A91F2 # device now has a certificate chaining to the product trust anchor
The certificate ties the device’s on-board key to your root of trust without your CA ever seeing the private key. The device proves possession of the private half by signing the request, the CA certifies the public half, and the secret stays on the device the whole time. Provisioning is also the moment to inject the trust anchor and any per-device configuration, so the device leaves the line already knowing who it is and who to trust, with no naive first-connect moment for an attacker to exploit.
Verify at End of Line
A provisioning step that silently fails is its own risk, shipping units with no key, a duplicate key, or an uncertified one. Build a verification stage that confirms each unit has a unique, properly certified key before it leaves the line.
# end-of-line check: device has a unique cert chaining to the product CA
verify_tool --check-cert --device $(read_device_serial) --ca product_ca.crtdevice 340A91F2: unique key OK, cert chains to product CA OK, not a duplicate PASS
That end-of-line check catches the failures that matter: a unit that never generated a key, two units that somehow share one, or a certificate that does not chain to your anchor. Catching these at manufacturing is far cheaper than discovering them as field failures or, worse, as a security gap.
Rejects, Repairs, and Re-Provisioning
Units that fail testing or get reworked are an overlooked hazard: a partially provisioned device can carry a half-formed identity or a key that should never have been certified. Treat provisioning as atomic and revocable, a unit either completes the full flow and gets a certified identity, or it is wiped and any issued identity is revoked, so a discarded board is not a discarded secret.
Devices also sometimes need a new identity, after a board repair that replaces the secure element, a key compromise, or a change of ownership. Design that path up front: an authorized service tool, gated by authentication, triggers fresh on-device key generation and obtains a new certificate while the old identity is revoked. Planning it early means a repair does not force a choice between an insecure shortcut and scrapping the unit.
The Pitfalls in One Place
The mistakes cluster into a short list, each of which quietly reintroduces a shared-secret or single-point-of-failure problem:
- A central server holding every private key
- The CA key stored next to the provisioning script
- No end-of-line verification of unique, certified keys
- No plan for rejected or repaired units
- Weak randomness on the device producing predictable keys
Reviewing a provisioning design is largely a matter of walking that list and asking where a usable secret exists outside a device and who can reach it. The ideal answer is that no usable private key exists anywhere but inside the device that owns it.
Where This Fits
Designing or reviewing a manufacturing provisioning flow, so per-device keys are generated safely and the line never becomes a vault of secrets, is part of a product security assessment. If you want a provisioning design review before your line spins up, that is the kind of work we do at Berkner Tech.



