Conclusion – Using a TPM for Your Server / Client Application¶
Over the last parts, we built a simple client/server application and gradually improved its security.
In Part 1, we started without encryption and demonstrated why this is a bad idea: an attacker could read the entire communication in clear text.
In Part 2, we added TLS for encryption, integrity protection and server authentication. At this point, we can be confident that:
- an attacker cannot read the communication between server and client
- an attacker cannot impersonate the server - the client verifies it is talking to the expected server
- an attacker cannot modify the data stream without being detected
In the third part we added client authentication (mutual TLS). The server can now verify that it is communicating with an authorized device - and not with a cloned device or a PC attempting to imitate it in order to use your server infrastructure.
In the fourth part we took a closer look at what a TPM brings to the table, including manufacturing and key deployment strategies. We also discussed why private keys are at risk when stored in the filesystem or handled in system RAM.
With Part 5 we used a TPM-backed private key in the Python client. The private key never leaves the TPM: it is not stored in the filesystem and it is never exposed as raw key material in RAM.
With Part 6 we repeated the same idea for a C implementation, covering both TSS2 key files and persistent handles.
All of these steps lead to one core goal.
Protect the private key and prevent it from being extracted.
What's next?¶
A TPM can provide even more security than "non-extractable keys". In particular:
Only allow use of the private key if the system is in a known-good, trusted state.
With the examples so far, access to the private key is effectively gated by:
- the TPM device itself, and
- the presence of a reference (a TSS2 key file or a persistent handle)
If an attacker exploits a vulnerability on the device, they still cannot extract the private key - but they may be able to use it indirectly (for example, to authenticate to your server as if they were your device).
So far, we have not enabled any TPM authorization policy. This "no additional authorization" model is common in embedded systems because it is simple and works well for many use cases. But for higher-security products, you may want stronger controls.
In the next step, we will look at TPM authorization mechanisms that restrict key usage - for example, enabling the private key only when the system is in a known-good state.
(Updates to this documentation will be added as these advanced topics are published.)