2

So in this scenario there are several programs that exist that can open and read a binary file, but my program must be the final arbitrator in creating and writing to these files.

In this program I am writing, I would like to detect if the file has been tampered with outside of my program's control. It is important that the other programs can still read the file, but that my program can refuse to open it on grounds it was edited outwith my program.

My solution is to distribute the file(s) with a list of checksums. If the corresponding checksum from the checksum list doesn't match the accompanying file, or the list does not exist, then that file is rejected.

My solution would be to calculate the hash using the following method:

sha256(HIDDEN_SALT + FILE_CONTENTS)

The HIDDEN_SALT being the key property that ensures outside sources couldn't spoof the hash.

In this situation, as the salt is applied to multiple files (1000+), would it be easy to crack by working backwards from the checksum(s) it was applied to? (Consider they have both the checksum and the file.) Would there be a better solution to this problem?

A Mac
  • 23
  • 2
  • Do the programs all run under the same userid? – paj28 Aug 17 '16 at 12:04
  • Unfortunately, no! Will be a distribution of OS's and machines. – A Mac Aug 17 '16 at 13:07
  • In that case, nothing you do will be secure against a determined hacker. However, a simple system like the one you propose will stop casual attackers. If the salt is large there's no chance of cracking it even with many files. However, they can simply extract the salt from your program. Your suggestion is vulnerable to an extension attack; use HMAC instead. – paj28 Aug 17 '16 at 13:13
  • 1
    sha3 isn't vulnerable to extension attacks, and it's not bundled with as many low-skill "crackers" – dandavis Aug 17 '16 at 20:34
  • You could use a MAC, or public key signatures, to make sure the file originates from you (or some trusted source). _But_ if the end user can modify the program, they can just disable the MAC/signature check. (basically similar to how copy-protected games were cracked in the times of yore) – ilkkachu Aug 21 '16 at 20:06

2 Answers2

2

There are actually two problems to solve for:

  • that the file has not been tampered with since creation by a trusted party
  • that a trusted party actually created the file in the first place

This is exactly the scenario that open source software distributors- RedHat, Ubuntu, MySQL, etc, etc- face in ensuring the integrity of the binary packages they release.

Their software, running on a consumer's computer, has to ensure both that a package the user has asked to install has not been tampered with by an attacker, and that it originated with a trusted source.

Hashing will help with the former, but public key cryptography is needed for the latter. The distributor- you and/or your delegates- publish their public key, and then cryptographically sign the distributed software using their private key.

The way this is usually done is by creating a cryptographic hash of the file contents- which can just be of the contents, and does not have to include a salt or anything- and then sign the hash, and distribute the signature, the hash and the file, along with the public key.

Then anyone can use the public key and the signature to verify that the hash originated with the holder of the private key, and then that the hash matches the file.

Take a look at "package signing" documentation from RedHat or Ubuntu using PGP keys for more information.

Jonah Benton
  • 3,359
  • 12
  • 20
  • I don't see why a HMAC is needed if you also use a signature. Isn't a hash enough? Besides, where would you store the symmetric key? Also note that you can aggregate hashes over many files (path, hash entries), and then create a signature over all the entries. Or you can put files or directories in an archive and achieve the same of course. – Maarten Bodewes Aug 22 '16 at 14:38
  • Yes, apologies, a secret is not required, and hashing the contents and then signing is just an optimization over signing the contents, and agree, the contents can be a archive file. Thank you for your correction, I will edit the answer. My point was more that a) there are two considerations, not one- ensuring the identity of the provider of the file, and ensuring the integrity of the file from the provider- and b) these considerations have been solved for for a long time by these other parties, and so understanding their approaches is probably wise. – Jonah Benton Aug 22 '16 at 20:47
  • If the everything, including the key is stored under the same UID, then an attacker who can write the files can also generate a new signature. – Adam Shostack Aug 22 '16 at 21:26
  • Thanks Adam, good point of course, will update the answer. – Jonah Benton Aug 22 '16 at 22:19
0

The operating system can help you, and you should leverage it. Let's call your program "ProgramA"

Create a new UID for ProgramA. Use operating system permissions to allow that program to only execute by that UID. Set permissions so that only ProgramA-UID can write. Set permissions so others can read.

(The same applies if you're on Windows, but with a SID and the permission labels are a little different.)

Adam Shostack
  • 2,659
  • 1
  • 10
  • 12