8

Say, I am running an application on a cloud server such as AWS. Suppose I supply a key at run-time (so its not stored anywhere alongside/inside code), is there a way to secure this key in memory?

So if an attacker gets access to the remote server at a later time, he still should not be able to extract the key from memory. Are there any ways to achieve this? Or is it known to be theoretically impossible?

The technique discussed here, transparent runtime security, is claimed to make it "difficult", but it may still be computationally feasible.

EDIT: Hardware based solutions are also ok.

  • 3
    The only thing i know about this is a sort of some obfuscation, meaning instead of storing the raw value in memory, you perform kind of some algorithm that will split it in memory and obfuscate it, add some random value. Then another algorithm will recompute it just when you need to use it, and will reset the memory where it was computed. – Walfrat May 3 '16 at 7:21
  • @Walfrat This sounds like the approach used by keepass to protect passwords in memory: Sensitive strings are kept encrypted, and after computation, they make sure to overwrite buffers with blank data before releasing them in order to "physically" erase their content. – Stéphane C. May 3 '16 at 7:33
  • You can store keys securily in memory by wrapping them with another key (ending with a key or password which is not in memory, obviously). The problem is using such a key, as you'd need to unwrap it first. What is sometimes performed is to unwrap the stored key in a hardware module. This is what TPM's and some HSM's do to keep larger quantities of keys than fit it in their internal, secure memory. This of course doesn't work as well in a cloud service, providing that the hardware is not available. – Maarten Bodewes May 3 '16 at 8:02
  • Yes, it is called homomorphic encryption. It is VERY slow though... – whatever489 May 3 '16 at 19:16
  • linux.die.net/man/3/memfrob ;) – Dog eat cat world May 4 '16 at 11:32
6

I answered a similar question here. For a normal hardware solution, a hardware security module (HSM) does this. For software, .NET offers the Secure String mechanism to encrypt and protect sensitive data in RAM. Other platforms may offer something similar. For an AWS solution, Amazon offers CloudHSM to do pretty much what you are asking for, I think.

From AWS:

HSM is short for Hardware Security Module. It is a piece of hardware — a dedicated appliance that provides secure key storage and a set of cryptographic operations within a tamper-resistant enclosure. You can store your keys within an HSM and use them to encrypt and decrypt data while keeping them safe and sound and under your full control. You are the only one with access to the keys stored in an HSM.

The AWS CloudHSM service brings the benefits of HSMs to the cloud. You retain full control of the keys and the cryptographic operations performed by the HSM(s) you create, including exclusive, single-tenant access to each one. Your cryptographic keys are protected by a tamper-resistant HSM that is designed to meet a number of international and US Government standards including NIST FIPS 140-2 and Common Criteria EAL4+.

3

While everyone else has suggested a hardware solution, I'll suggest a software solution (though I don't mean to imply that it's any better or worse than using an HSM - that you'll have to decide on your own based on your own needs). This solution is a kernel patch which encrypts processes.

RamCrypt is a project which encrypts the majority of the memory of individual processes with AES128 in XEX mode, so all secrets in the processes are safe in memory, even if all of the memory is forensically acquired. The memory is encrypted with TRESOR, so the encryption key is never present in RAM. It keeps the key in the x86 debug registers, so they are out of memory, and does all the AES computation using AES-NI, general registers, and SSE registers, so it never enters main memory or CPU cache. The key is then used to encrypt and decrypt memory pages for an entire process. Only 4 pages are kept unencrypted, and all others are encrypted. When an encrypted page needs to be accessed, it is decrypted using the AES key, and one of the 4 unencrypted pages is encrypted. RamCrypt comes as a kernel patch, and you can adjust the number of pages which remain unencrypted to choose a trade-off between performance and security. See the project's main page, and the associated research paper.

  • I think this is an interesting comment, but I don't see that it would work for AWS. AWS runs on virtual machines, so it seems to me that anyone with access to the host machine could simply find the key in the register. – Steve Sether May 4 '16 at 14:45
  • This comes close to a software-only solution. Its still not clear to me if this really works. I'm reading the references. Possibly it could be bootstrapped using a hardware module to ensure that RamCrypt has been booted securely. – Jus12 May 4 '16 at 15:31
  • You're right, it wouldn't work on AWS, since virtual machines trap access to hardware debug registers and emulate it. This is more about generally keeping secrets safe in memory. This is not possible on a virtual machine unless it is designed with this in mind (e.g. by isolating individual VMs with SGX). – forest Dec 1 '17 at 5:44
1

I'm not sure if I get you right. But at some point the plain secret has to be in some sort of memory (most likely the RAM). If the attacker can read the memory at that point and if he is able to find the secret he can decrypt the data afterwards.

I think theoretically there can't be a way (maybe with some special security module that contains your program code) to save the secret in memory without any chance the attacker can find it. There is always an algorithm that can find the key (there has to be because you want to use the key in your own code). But as pointed out in the paper it can get really really hard to find the key.

Just a side note: I also don't see the use case of generating a random secret that no one knows and then not store it anywhere.

Cheers

  • Not a random key but one entered by a human during run-time. – Jus12 May 3 '16 at 7:47
  • 2
    Usually humans enter passwords, not keys (although some key management routines may require direct entry of hexadecimals representing bytes of a key). Never confuse passwords and keys. – Maarten Bodewes May 3 '16 at 8:05
  • 1
    If you mean passwords to be alphanumeric, then I don't technically distinguish between a key and a strong password. A Base64 encoded 256 bit random key is also a password under this definition. – Jus12 May 4 '16 at 3:38
  • (maybe with some special security module that contains your program code) -- This might seem to work. However, isn't it 'turtles all the way down'? Because then we need to control the code that uses the program that uses the key. – Jus12 May 6 '16 at 17:30
1

Fundamentally, there is nothing that can solve this issue in the absolute. You're running into the DRM problem, which is that you need plaintext access to some data on a system in order to fulfill some functionality, but you're also placing that system under the control of a party which is untrusted. The best you can do is make it incredibly difficult for all but the most determined and skilled attackers, essentially making it a poor a cost/benefit trade-off for them.

In terms of solutions which do make it hard, devices such as Hardware Security Modules (HSMs) should be pretty much top of your list. They utilise a range of features designed to make it exceedingly difficult to recover information from them illegitimately. For example, a common feature is to encrypt data with a key stored in volatile memory (e.g. DRAM) on a separate board, physically attached to the upper casing of the device. The power and data connections for this board are supplied via a contact connector (often made from conductive polymer or foam) via pads on the main board, which is physically attached to the lower casing of the device. If you attempt to open the device, you separate the boards, thus disconnecting the power from the DRAM and losing the keys. Additional sensors such as light, temperature, pressure, acceleration and position (incl. GPS) and even magnetic fields or radiation can be present in order to detect different types of tampering.

One additional potential system which may, in some circumstances, be of use to you is the concept of homomorphic cryptosystems. Homomorphism, in laymen's terms, is essentially the property of a cryptosystem that allows certain operations to be performed on data in its encrypted form, without needing to first decrypt the data. There are a variety of schemes available, some of which are even practical for certain types of scenarios, but they are usually quite complex in nature and can be particularly slow. I am unaware of any existing cryptosystem which provides homomorphism in a way that would be conducive to cloud storage applications.

  • Note that there is a subtle difference. In the DRM case, the device/application is bootstrapped in a compromised state. In my case, I can guarantee that my application (say, a custom made media player) was bootstrapped in a secure state when the key was supplied. Later at some point, the system is compromised. This is a weaker requirement than the pure DRM case. – Jus12 May 4 '16 at 3:35
  • @jus12 "In the DRM case, the device/application is bootstrapped in a compromised state." - not with secure boot! – immibis May 4 '16 at 5:24
  • 1
    @Jus12 I don't believe that you can bootstrap to any safe state when the underlying hardware is controlled by a potentially malicious party. – Polynomial May 4 '16 at 12:21
  • @Polynomial That is one of the assumptions I am making. The underlying hardware was in a trusted state at the time when the key was supplied. It may later become compromised. I feel there is a difference in the attacker capabilities in these two cases, even though they appear to be similar. – Jus12 May 4 '16 at 15:33
1

It depends.

Other posters suggest an HSM. This can be a good solution for a limited set of purposes where you temporarily need access to a key, it's erased from active memory after, and the key to the HSM itself isn't stored in memory long-term.

It sounds like you need the secret to be active in memory all the time, and not stored in an HSM most of the time. In that case, I don't see much value in the key storage capabilities of an HSM, since it can't protect keys already stored in memory.

And HSM can also perform the cryptographic functions in the module itself. Whether this is useful to you or not would depend on your application.

  • Yes, for my application, the key is used consistently. If this can be done via HSM, this would solve the problem. How can we prevent the attacker from using the key inside the HSM? – Jus12 May 4 '16 at 3:31
  • @Jus12 I don't know that you can. While the key is in use, it's in memory. If it's in memory, it's at risk. Think of the HSM as a safe. If the secret is outside of the safe, it's not protected. When it's ONLY in the safe, it's protected, but you still need to store the combination somewhere. If the combination is in memory, you haven't really accomplished anything but misdirection. – Steve Sether May 4 '16 at 14:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.