Save to store encryption key in Go executable?

2,647 views
Skip to first unread message

Haddock

unread,
Jun 13, 2016, 12:01:48 PM6/13/16
to golang-nuts
Hello,

I'm developing my own little encryption application in Go. The Go application needs to know the key used for encryption and decryption. My question is whether that key can be extracted from the Go executable somehow through disassembly or looking at the applications memory or something. I'm a complete Go beginner and know nothing about its memory layout. So that's why I thought it's better to ask.

Thanks, Haddock

Axel Wagner

unread,
Jun 13, 2016, 12:07:42 PM6/13/16
to Haddock, golang-nuts
Yes, it can (though that's not specific to go) and it's a theoretical impossibility to prevent it (otherwise DRM would be a *really* simple problem to solve…).

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Evan Digby

unread,
Jun 13, 2016, 1:06:12 PM6/13/16
to golang-nuts
As Haddock stated, it is basically impossible to prevent it from being accessible to someone looking. Embedding as plaintext will be trivial to extract, and essentially any method you use to encrypt/obfuscate it (encrypt the encryption??) will only be slightly less trivial to extract. Typically not worth the upfront cost/effort unless delaying access to it for a short period of time (not preventing access) has value to you.

I worked in DRM for 5 years we were happy if we could give a tier 1 client 24-48 hours of un-cracked sales (longer for smaller releases). No binary is immune to cracking because at some point, no matter what the obfuscation, the data/code you're trying to protect (like your encryption/decryption key) has to be in memory unencrypted to be usable by the process/CPU/user. Given this, the method of decryption has to exist within the binary, and therefore is accessible to a cracker.

With that in mind hopefully it's clear why you can't expect any data/code to be forever inaccessible, and therefore it's not safe to include secrets in the binary.

Why do you need to store the key inside the binary, rather than having it stored in some config read by the binary? Can you pass the logic that requires the encryption to a server-side service and then authorize the users in a standard way?

With more details on your specific use-case I (or others here) may be able provide guidance towards an alternative solution. 

This also branches the conversation outside of the realm of Go-specific, so there may be other resources available to you if you think of your question in terms of compiled binaries in general, and not just Go language. 

Evan Digby

unread,
Jun 13, 2016, 1:17:38 PM6/13/16
to golang-nuts
Apologies. I meant "as Axel" stated :)

as....@gmail.com

unread,
Jun 13, 2016, 11:19:08 PM6/13/16
to golang-nuts
This is a key distribution problem, if you store the key in the executable you should assume everyone already has access to the key. This is a different problem than "can someone get the key out of running memory". If you store the key in the executable, then an existential compromise of this key in any copy of the program compromises the secrecy of all past, present, and future processes that use this program. The point is, the key should be stored outside of the program.

Have you thought about having the program read in a passphrase, feeding it into a good key derivation algorithm, and then using that symmetric key to encrypt and decrypt your data (with something like AES GCM)?  

Haddock

unread,
Jun 14, 2016, 1:12:25 AM6/14/16
to golang-nuts
Thanks for all the useful answers. All I want to do is to create an encryption program for simple home computing purposes. I once lost some encrypted files, because I lost the password. I think I did a typo when typing it in and didn't realize. So I thought I write my own encryption programm with a catch-all password in it. That might be a very bad idea now ...

I first wanted to use Java as I'm used to it. But Java code cannot be encrypted to hide the encryption key, because the Java byte codes would then become unreadable for the JVM. So I thought of something else. I thought of moving the key to some server. But then I would be dependent on some server and the Internet being reachable in order to decrypt my things (password files, etc.).

Seems like the best solution would be to store the key in a separate file, though I don't understand exactly how this makes things better. Having the key in a separate file means that the decrypted blank key is only visible from within the running encryption programm for a very short moment. Is that the idea? Maybe have a solution that first looks for a local key file and only checks some server for it when locally not present.

Regards, Haddock

as....@gmail.com

unread,
Jun 14, 2016, 2:57:35 AM6/14/16
to golang-nuts
You're right, even if you aren't planning to share the program, it's still a good idea to separate the key from the executable. For one, the executable is bigger and harder to keep secret than a few bytes of data. It's generally frowned upon to bundle the two since the secrecy should rely solely on the key.

If you don't like passwords, you can store the key on a flash drive as a file or even write it directly to the underlying block device.

Evan Digby

unread,
Jun 14, 2016, 12:55:00 PM6/14/16
to golang-nuts, as....@gmail.com
Unfortunately there's a reason why password managers still require a passphrase. It's simply not secure to store the key anywhere near the secure files. 

I'm not saying password managers are perfect--they have their own security issues--but it seems that you're attempting to closely mimic that functionality (except for data instead of passwords) while removing the requirement for a passphrase. I would investigate the security model of some well respected password managers as a foundation to give you some insight/inspiration. 

I like the idea of storing your key on a flash drive--it seems to be the best suggestion here so far, but honestly that probably won't be much more secure than simply writing your passphrase down and keeping it in your wallet. 

Trusting a device or piece of paper also has a steep downside: it can be lost just as easily as your memory--maybe more easily. Depending on a device and then losing it is just as devastating as forgetting the passphrase so this doesn't really meet your requirements given the inspiration behind this project. 

Storing your password somewhere in the cloud as a backup can be a form of poor mans two-factor authentication/password recovery. You can try to remember the passphrase (or not lose the device/paper), or you can remember your account details for the backup. Gives you two shots at recovery (three if the cloud service has a password recovery option). 

Please note, however, that the more places you put the passphrase the less secure it is, but it sounds like you need "good" encryption with a near zero percent chance of losing the encrypted data, as opposed to "great" encryption with a high chance of losing the encrypted data. The more secure you need it, the closer you approach needing a brain-memory only long passphrase that is (for some) easily forgotten but impossible to extract digitally.

Back to your implementation, I agree with the advice that it's best to keep the passphrase/key separate from the binary. I would start by investigating "non-lose-able" (technical term :P) and reasonably secure methods of storing that passphrase separate from the binary (and even the system that stores the data) as a priority over the encryption software itself. See how that works with existing encryption solutions, and then make the encryption "phase 2" of your project. 
Reply all
Reply to author
Forward
0 new messages