I want to do the below. What is the best way to achieve this?
- I have a desktop app in C# which will be installed on multiple client machines.
- The application is capable of doing an operation X but it needs some auxillary info which it can read from a file. This auxiliary info essentially provides some specifics that identify that machine where the operation should be run and what operation to run etc.
- I will work with the client to get some of this auxilary info about his machine (say hostname/ip address etc) which I want to put in this file along with other info and generate it on my machine and share it with him/her to provide it to my software. I want to encrypt this data so that the structure of the data is not obvious to somebody who opens it. (I will get some of the machine identification info from the client, either via phone or email).
- I want to somehow encrypt and secure this file such that only I can generate the file but any of my installations can read it. But since the contained info is specific to a machine it will be executed only on one machine (other machines will read but reject it since the given hostname/ip etc won't match that machine)
- How do I do this? I want to make sure the below:
- Only I can generate this file.
- I need to somehow authenticate that this is generated only by me and not by somebody else.
- But my software on client machines should be able to decrypt this.
- I don't want to take a password from the customer etc. all the decryption logic should be in the installed software itself. I want to code it in.
When I researched this online, many talk about public and private cryptography but there they talk about encrypting with the public key and decrypting with the private key. But I don't think this will work since decryption is being done by my software at the client machine and so I shouldn't put the private key in my code. Because, from what I read, private key can generate public key so somebody could potentially generate that instruction file if I do this.
What is the best way to do this? Can I encrypt with private key and decrypt with public key? Is it ok if somebody gets hold of my public key (say they disassemble the C# code)? Any other good ways to encrypt and authenticate such that I hold the private data with me but code only harmless public keys/data in the application?
TIA.
CodePudding user response:
Who are you trying to protect this from?
You are giving the end user your application binary. Assume they can decompile it and work out how it works. Or step through your code in a debugger, with access to the contents of every variable. Assume that an attacker can learn everything they need to know about how it works.
At best I would recommend creating a hash of the machine details and a salt value. Then create a signature of that hash.
Keep the salt and the public key of the signature as a constant in the application binary. Maybe XOR values together so an attacker has to think a little about how it works.
But anything more is pointless. Any attacker with more skills will just patch your program to delete the test entirely. So I wouldn't bother building anything too complicated.
Giving someone a program, and preventing them from using it, is like trying to make water not wet.
CodePudding user response:
You have two questions
- How do you encrypt the information, and
- How can your client make sure the information came from you.
Those are orthogonal
I'll address the second on first - it's easier.
First, hash the file, and add the hash to the payload. Then generate a public/private key pair, then encrypt some known (but non-trivial) information with the private key and add that to the payload. You can distribute the public key with your app. If your app hashes the file and the hashes match and it can decrypt the known information and make sense of it, then it came from you and no one has changed it.
This is known as a digital signature. If you look up a digital signature provider and follow the docs, it should just work.
The encryption problem is more of an issue. There's pretty much no way to do what you want. If your app can decrypt the information using information you distribute with the application, then a determined bad guy can extract that key material and decrypt it.
However, you can use the RSA key container on the client to do the encryption when you install the app. The process is similar to using encrypted sections in a web.config file. Since you won't be following the encrypted config section cookbook the process is complicated.
I've done this before, but it was several jobs ago, so I don't have anything I can show you.
But, it will be encrypted so that it can be read only where it was encrypted. No two installations will recognize each others files.
That said...
Encryption seems like a heavy hammer to prevent your customers from being able to guess "the structure of the data [so that it] is not obvious to somebody who opens it"
Unless you have something worth protecting, you can probably get away with obfuscating the data. For example, you could have the data as JSON, but then use GetBytes
on a Utf8Encoding to get a byte[]
and convert that to a hex string. A determined hacker could decompile you code, figure out what you've done and reverse it, but that doesn't seem like a threat you really need to worry about.