22

Let's say I've retrieved an encrypted secret key from the server. I decrypt it to get the actual secret key, assign the decrypted key to a variable in my app. Something along this:

const encryptedKey = fetchKeyFromServer();
const secretKey = decrypt(encryptedKey);
//Now, the variable secretKey has the actual secret key in memory

Now, is this a vulnerable thing to do in terms of security? Since I've stored the decrypted key in the memory, is there a chance that somebody might be able to reveal the secret key by reading off from the app's memory?

However, if I don't assign the decrypted key to a variable, how should I use the key? I've thought of assigning the encrypted key to the variable and decrypt it every time I need to use it. But I'm still not sure if this is the best way to do things.

  • Do you have a specific programming language in mind? – Sjoerd May 10 '17 at 6:45
  • @Sjoerd I'm using javascript with react native. so the app will be deployed onto phones. – xenon May 10 '17 at 6:46
  • 5
    See also How to clear sensitive memory in JavaScript? – Sjoerd May 10 '17 at 6:51
  • @Sjoerd thanks! looks like from the accepted answer, there is no way I can clear sensitive memory in JS. :( – xenon May 10 '17 at 6:58
  • Who owns/controls the machine this program will run on? The secret key's owner or someone else? – das-g May 10 '17 at 12:22
32

Yes, it does mean that the key will be stored in the application’s memory. Yes, there is a risk that malware (with sufficient privilege) can read it from there. This risk is hard to avoid — if you want to use the key, you need to put it in memory, just as you need to put your house key in your pocket after you lock the door.

This is usually not considered a big deal for one reason — if there is malware with root privileges on a computer it’s already game over anyway. There is no way to keep anything safe at that point. Even if you don’t decrypt the key, the malware could just read the key that is used for that decryption from wherever it is stored.

Here are three things you can do to mitigate the risk:

  • Use some kind of HSM. (Thanks to DRF for pointing this out.) This is the best approach, but the feasibility depends on what platform you are working on. Do note though, that malware with enough privilege to read other processes’ memory can probably use the HSM as well. So this is not bulletproof against a malware infection.
  • Minimize the time the key is in memory to shrink the attack window by overwriting the memory after you are done. (As MSalters points out, this might not be as straight forward as it sounds. E.g. in C++ the optimizer might remove a write that is not read, and in Java strings are imutable so they can not be overwritten.)
  • As Vitor suggests, mark the memory page the key is stored on as unswappable so that it is never written to disk.
  • 6
    You are ignoring possible other solutions such as HSM's which can solve this problem at least partially (you still end up with plaintext in memory but not keys). Since more and more devices have some form of partial HSM built in, in the form of a dedicated security chip or a smart card, this becomes more feasible. – DRF May 10 '17 at 8:07
  • 17
    "In a language like C++ it is fairly simple — you just write zeroes over the memory where you stored it.". And then the optimizer says "hey, that's a write without subsequent read, let's optimize that". That's why Windows has ZeroMemory and SecureZeroMemory – MSalters May 10 '17 at 13:02
  • 2
    Another good thing is to tell the OS to mark the memory page where your key is stored as non-swappable, to avoid having it written on permanent storage – Vitor May 10 '17 at 14:28
  • 2
    If you are using .NET, you can use a SecureString. Unfortunately the documentation suggests this is not available for mobile, but could be useful for anyone writing a Windows desktop app. – IllusiveBrian May 10 '17 at 14:47
  • 2
    From what i've seen, SecureString is very easy to use incorrectly. If you ever convert it to a string, or have an array containing the characters/bytes in the key, you've just tossed out nearly all the protection it can offer you. – cHao May 10 '17 at 15:17

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