Search code examples
linuxsecuritydigital-signatureprivate-key

Let an app sign documents, but don't let it see the keys


I want to digitally sign documents and messages on a Linux server. How do I securely store the private key and a passphrase if any?

The problem is, if an application gets compromised, keys would also become compromised. If I could somehow let an app sign something, but don't let it touch actual keys, that wouldn't completely solve my problem (as an attacker would still be able to sign anything for some time), but reduce the impact (like, we won't have to revoke the keys).

For example, in case of SSL servers there's no such problem because usually there's no practical need for an application to access the keys. Hence, they can be semi-securely stored in a separate location. E.g. a webserver (like nginx) would be able to read the keys, but not the application.

Am I overthinking it? Is it even worthy thinking of?


Solution

  • Create a separate, lightweight signing application that listens on an UNIX socket and runs as a separate user from the main app; when your app wants to sign something it throws the file and any additional info down that socket, and gets back the signed file.

    If the application ever gets compromised the attacker will still be able to sign files as long as he is still on the server, but unless he uses a privilege escalation exploit to get root privileges and copy the signing app's key, he won't he able to steal the key and then sign at will without being connected to the server.

    You can replace the UNIX socket with a standard TCP socket and put the signing app on a separate server for extra security; make sure to implement some basic access control on the signing app and of course use proper firewall rules to make sure the signing server is never exposed to the internet, or simplify things a bit by using a "setuid" binary for signing that gets invoked by your app, in that case the signing binary will run as a different user with additional privileges to access the keys, while the webapp itself doesn't have such privileges.

    Basically you should implement a rudimentary software HSM.