Java: Possibilities to protect files against manipulation

老子叫甜甜 提交于 2021-02-18 19:24:32

问题


My Java program builds some files (.html and .txt-files) in one directory. To finish a project I'd like to "pack" these files for example to send it to another person. But the other person should not be able to simple "unpack" the file and manipulate the html/txt-Files. Only open the packed file with my Java program.

My idea was, to zip the directory with a master password (set in the Java program) protection. After that I can send the zip-file via eMail and the other person will only be able to open it with my program. Unfortunately there is no easy and free way to zip/unzip a folder with password in Java.

So maybe you have another idea?


Ok I think I have to explain the problem a little bit more: I can create a small training with my program. The training contains "normal" pages with information (html-files) and pages with multiple-choice questions (the question and the answers are saved in txt-Files). In the end, the training-user can print a certification ("User XXX did the training"). To play the training the html/txt-files are read into my program. Ok so my problem is that the user can see (and manipulate) the files. However he can see the right answer of the multiple choice test in the txt-file.


回答1:


There is no 100% way to stop people reading files, but you can make it a lot more difficult. What you are need to do is encrypt the file to prevent casual reading, or to sign the file so that you can detect authenticity and tampering.

Here is an overview of how you might encrypt a file with public / private key encryption. The tools you will need are:

  1. GPG. You will be creating keys with this
  2. BouncyCastle PGP. This is an encryption API for Java that implements the OpenPGP specification.

You will be encrypting files with the command line with GPG and reading them from Java with BouncyCastle (BC).

The steps involved in doing this in a secure way are.

  1. Create a unique public / private key pair for signing / encryption with GPG. e.g. gpg --gen-key and follow the onscreen instructions. You can usually pick the default settings, and call your key something like "app-security-key@mydomain.com"

  2. Encrypt the file your Java will process. e.g. gpg -e myfiles.zip to encrypt. You could do this from a script fairly easily if its data that changes a lot. Encryption works by encrypting the file with the public key. Someone who wishes to decrypt the file needs the corresponding private key.

  3. Export the private key from the keypair. e.g. file gpg --export-secret-key -a > decryption.key.

  4. Create a new keyring just containing the key you exported. e.g.

    mkdir tmpkeys gpg -homedir=tmpkeys --import decryption.key cp tmpkeys/secring.gpg keyring

  5. In your Java program, embed the keyring as a resource or by base64 encoding it and injecting it into the code as a string. Keep your public key and ensure you do not inadvertently ship it with your app.

  6. Use BouncyCastle PGP to open the keyring.

This is pseudo code, so read the BC APIs for details.

// During initialisation
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

// During decryption
InputStream is = openKeyring(); // Wherever your keyring is
InputStream isData = openDataFile(); 

try {
  PGPSecretKeyRing kr = new PGPSecretKeyRing();
  PGPSecretKey sk = kr.getSecretKey();
  PGPPrivateKey pl = sk.extractPrivateKey("mypassphrase", securityProvider); 
  PGPObjectFactory of = new PGPObjectFactory(isData);
  Object o;
  while ((o = of.nextObject) != null) {
    if (o instanceof PGPCompressedData) {
      readAndDoWhateverINeedtoDo((PGPCompressedData) o).getDataStream());
    }
  }
}
catch (Exception e) {
  rejectFile(e);
}

So basically the Java app gets an encrypted file, gives it to BC along with the private key and gets back an InputStream that it can read the plaintext from. If it has a problem it will throw an exception that you can treat as a fatal error.

Note a few things:

  1. You will need to embed a passphrase somewhere in the Java app, but it doesn't have to be the same one that protects your public key. Remember we exported the private key into a temporary keyring so you could change the passphrase there.
  2. A determined attacked could still hack your Java file to extract the private key & password, or print out the plaintext or remove this test altogether. I suggest if this is a worry you should be obfuscating your code and putting surreptitious checks to ensure validation is not bypassed in some way. Nothing will prevent this 100% though.
  3. Just signing a file is similar to encryption except you give out the public key and keep the private key secret. In this case the Java app can detect file tampering, but the payload is plaintext.
  4. BouncyCastle is straightforward when you know it, but the documentation is terrible. You should download the source code since there are some test samples which will put you on the right course.



回答2:


One thing that you can do is generate a CRC number for each an every file you want and pack it in a property file along with the jar file.Each time the user selects the file, check for the CRC value to make sure no-one has edited your files.It's not completely fool proof method.

Similar Questions:

  • Prevent External XML modification
  • CRC check for files

Other Useful Links:

  • Load a Resource From jar (SO Question)
  • Load image from jar (Java's site tutorial)

Just like the image is loaded dynamically from jar in the above given link you can load html and txt files from jar.




回答3:


What you are asking for is fundamentally impossible to do in a secure way, (unless all the interesting stuff happens on the server) - just ask anybody who's tried to make a DRM system recently. (I'm looking at you, ubisoft).

If you are just looking for a simple check that will stop a (very) casual attacker, how about storing your support files in a zip as you mentioned, and compare the SHA1 sum to a value coded into your program at runtime. Somebody can modify your code (or for java use a decompiler) and remove the check, but it's as good as anything really.




回答4:


Unfortunately, there really isn't much to be done. This is one of the advantages of writing web applications; the user sees only the inputs and outputs, but doesn't actually have access to the application, itself. Whenever you distribute an application such as a JAR, it is always possible to reverse-engineer and modify it; no obfuscation or encryption can thoroughly or completely prevent it.



来源:https://stackoverflow.com/questions/3698572/java-possibilities-to-protect-files-against-manipulation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!