0
$\begingroup$

I'm designing a program that clients can download to the computer. This program needs to sync with my online server on a regular basis to confirm that the client's Activation Code hasnt expired and they're paying their bills. However, I want the program to be able to run for a period of up to 5 days without having to connect. This would allow the client to use the program for a time if they lose their internet connection. This would be a big bonus over other programs my clients use that become completely useless without internet.

To achieve this, I want to store a timestamp in a local text file. Every time the program runs, it can check the timestamp to see if an online sync is required. So if 5 days pass without a sync online, the program will refuse to start until the client syncs again.

The problem is how do I securely store this file so the client can't tamper with it. If the client can just open the text file and change the timestamp, the program could be tricked into thinking it never has to sync.

I have considered the following:

  1. Storing a symmetric key inside the program that's used to encrypt the text file, then decrypt it when needed to ensure its authenticity. The problem here is that the symmetric key would have to be fixed and stored within the program. I'm a newer programmer in Java but from what I understand programs can be reverse-compiled and the symmetric key obtained. Also this symmetric key could reside in memory and be obtained. All distributions of the program would have to have the same symmetric key built in (I suppose), and this would be a problem would it not?

  2. Some way of signing the file to ensure the authenticity. I don't know much about encryption but this sounds exactly like #1.

  3. Asymmetric encryption. But I'm not sure how that could be achieved here. When the program syncs, the online server could encrypt a timestamp with a public key and send it back to the program to store the encrypted contents in a file. Then it could be decrypted with a private key. This would ensure the timestamp was created by my server and not the client. The problem is anyone could encrypt a timestamp with the public key and place it in the file, because the public key is public. Also the private key would have to be stored within the program, which is back to the same problem as #1.

Is it even possible to achieve what I'm trying to achieve?

$\endgroup$

1 Answer 1

0
$\begingroup$

The problem is how do I securely store this file so the client can't tamper with it. If the client can just open the text file and change the timestamp, the program could be tricked into thinking it never has to sync.

I have considered the following:

  1. Some way of signing the file to ensure the authenticity.

That would be the closest; the obvious way would be if the server had a private signature key, and the program had the corresponding public key. Then, when you are connected, the server could sign the current time stamp, and send that time stamp and signature to the client.

Then, when the client cannot connect, he then checks the more recent time stamp/signature that was downloaded, and verify that signature (using the public key that's installed with the client); if that validates, then you check if the time stamp is no more than five days old.

In addition, you can include a hash of some relevant files (ones that the client should not modify) in with what the server signs; at verification time, the client would hash its copies of the files and include that in the verification.

The attacker cannot modify the time stamp, because he cannot modify the signature (and have it verify); he can replace the timestamp/signature with a previous one, however that wouldn't gain anything.

Possible ways to attack this:

  • Modify the 'current time'; most OS's allow you to set the time to whatever the user wants. This assumes a validated (if not particularly precise) timestamp.

  • Modify the program (either to modify the public key, or more likely, replace the validation logic with something that always says 'it's valid). That's always an issue when you're running in an untrusted compute base.

$\endgroup$
3
  • $\begingroup$ Hey @poncho thanks for all the great ideas. I will take some time to digest this and get back to you. Gracias $\endgroup$
    – Geoff
    Commented Mar 14, 2022 at 23:13
  • $\begingroup$ I appreciate your help. I think I get what you're saying. Asymmetric RSA encryption can be used in reverse, where the private key signs something and then then public key can be used to confirm authenticity. Store the signed version and the original message, then make sure they match. The signature could only have been from the private key. Makes sense. As far as attacking it, Is it possible to modify the code in a compiled program? I don't know much about that. Can basically any program be modified and its just something developers have to live with? $\endgroup$
    – Geoff
    Commented Mar 14, 2022 at 23:32
  • $\begingroup$ @Geoff: "As far as attacking it, Is it possible to modify the code in a compiled program?"; it's not trivial, but it can be done by someone with a bit of experience and the right tooling. $\endgroup$
    – poncho
    Commented Mar 15, 2022 at 3:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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