As part of an ongoing series, we’re taking a deep dive into the structure, use, and benefits of various crypto tools for devops.
Different environments have different needs for managing secrets securely. While tools like HashiCorp Vault are great for managing system-level secrets, some applications have more precise requirements for credential management. When managing credentials for Android projects or server-side Java code, most developers will need to use the Java KeyStore instead of other tools.
That’s not to say the Java KeyStore is the only option for managing credentials and secrets on the application level, but it is one of the most accessible for Java developers.
The Java KeyStore itself is a repository managed by the JDK (Java Development Kit) that stores certificates and keys for use by a Java application. Primarily, developers use the KeyStore to store entries – private keys for asymmetric encryption, secret keys for symmetric encryption, and trusted third-party certificates.
Developers create individual KeyStore instances programmatically as needed within their application. These stores can be transient (i.e. caches of credentials held in-memory), persistent (i.e. writing data to disk), or privately hosted through the use of smart cards or other integrated cryptographic systems.
DevOps Use Case
Again, the Java KeyStore is not a tool meant for the broad management of systems-level secrets or credentials. Instead, it’s used to house the keys and passwords needed on an application level in code. The KeyStore itself is an interface that does not dictate the underlying storage of the secrets it manages. This data could be stored unencrypted in memory, encrypted at rest on disk, or protected in a hardware security module (HSM) or smart card.
The advantage of the Java KeyStore is most noticeable when paired with secure hardware in this way. In reality, that is how it works inside Android systems:
Android Keystore system protects key material from unauthorized use. Firstly, Android Keystore mitigates unauthorized use of key material outside of the Android device by preventing extraction of the key material from application processes and from the Android device as a whole. Secondly, Android KeyStore mitigates unauthorized use of key material on the Android device by making apps specify authorized uses of their keys and then enforcing these restrictions outside of the apps’ processes. (Android Keystore System)
Server-hosted applications can leverage similar secure hardware (like an on-premises HSM). Client-hosted applications beyond Android can use similar tools, like a Yubikey, to prevent keys from being extracted and transported to new locations.
The Good and the Bad
In any environment, the Java KeyStore presents application developers with a secure way to use credentials without explicitly loading those credentials into the application in a manner that could be exploited.
However, the Java KeyStore has the same limitation present in nearly all credentials management systems: there needs to be a secure way to get credentials into the storage system before an application can make use of them. In a handful of cases, developers can pre-load credentials into a secure hardware module before distribution, but this isn’t a general-purpose solution.
If you use Java to build your applications, either for Android or other platforms, it would be a good idea to review Oracle’s documentation on the KeyStore in detail. It is also educational to see how other developers have integrated their hardware-based security systems (like PIV smart cards) with the KeyStore.
If you don’t use Java, it’s still a good idea to review how credentials flow and are secured in the Java world and compare to how things work on your own systems. Similar to the Android implementation of the KeyStore, Apple ships a “secure enclave” with iOS devices to securely house and manage credentials in a way where they cannot be extracted from the device (PDF).
As useful as local management of secure credentials can be to a developer, there are still serious limitations to the implementation. We’ve already covered the need for a secure “bootstrapping” mechanism to deliver credentials in to the KeyStore. Next week, we’ll wrap up our series and talk about a potential ideal utility that provides the developer ease-of-use of the KeyStore without the fatal omission of bootstrapping support.