I am trying to figure out how to write a simple Java Class to encrypt and decrypt plain text files, using AES but it has to be able to tell if someone else has someone edited a file and encrypted it outside of that class through a use of a signature. If the signature doesn't match then the file gets deleted.
I had a look at Message Digest and though about storing a checksum in another file, but I would like some advice. Is there any way that we can easily implement that. The Java Class will need a function to be able to go through a folder and see if files have been tampered with.
What you want is authenticated encryption (aka AEAD). A very common way to achieve this is to use AES in Galois Counter Mode (GCM). Please keep in mind that this mode provides great security and efficiency when used correctly, but when used even slightly incorrectly all those benefits can quickly go out the window. For example, if you reuse an IV for different plaintexts you lose almost all your security assurances. If the terms I am using are foreign to you and the data you are trying to protect is very sensitive, I highly recommend that you hire someone knowledgeable in the field to do this for you. If you still wish to do this yourself you will need to first figure out the following:
How will you generate your AES key(s)? The source of entropy for this is important and needs to be appropriate for the sensitivity of the data you wish to protect.
How will you store your key(s)? Will they sit in a software-based keystore on the local machine or will they sit in some kind of tamper resistant hardware (e.g., an HSM)? If they will be only protected by software, how will you protect the passphrase(s)?
How will you store the ciphertext, IV, auth tag, and associated data? Will you use a predefined format (e.g., CMS) or a custom homegrown one?
In addition to files being modified, do you need to test if files were deleted and/or duplicated from the directory?
What length authentication tag would you like?
I am not sure how big your files are so I don't know if you want to read the entire file into memory and then perform encryption or use an Input/Output Stream approach. If you let me know more details I can point you to some better resources.
Related
I have an encryption program and I was looking for a way in so that only the encryption program have access to they keys folder. But setting it to the owner or anyone in the users aren't a good idea. I was thinking maybe something like Steam did with its folder. It restricted access even to the owner/admin of the computer and only the Steam app can communicate/edit/access the folder. I was wondering how to do it in Java.
The code that I currently have right now is this.
Path file = Paths.get("F:\\keys\\pic.datakey");
UserPrincipal owner = file.GetFileSystem().getUserPrincipalLookupService()
.lookupPrincipalByName("username");
Files.setOwner(file, owner);
with keys being the folder name and pic.datakey is the key that I'm trying to prevent anyone except the program to have access with.
How to set the folder owner to the encryption program's?
The encryption program is not a principal. It cannot own things. What you need is to run the program as some special principal1.
Problems:
What principal should you use? There won't be a platform-independent answer to that. Indeed, there isn't an obvious platform-specific answer, at least for Linux.
How do you ensure that the encryption program runs as the designated principal. This is not solvable in Java. (Long story ... but mechanisms like UNIX setuid will require a non-Java (non-shell) launcher to implement them securely for a Java program.)
But once you have done those things, it will be unnecessary to change the owner of the file (as per your code). The owner will default to the principal under which the program is currently being run.
But here's the real question. What do you think you will achieve by hiding the encryption keys from the user who has encrypted the file?
If we assume that the user has full "root" access (or equivalent) then they can access any file stored locally on the system, either directly (i.e. as root) or with some extra effort. Certainly on a typical operating system.
And the flip-side is that if the user doesn't have "root" (or equivalent) access, you can stop him / her from seeing files by setting the owner / permissions of the files. Adding encryption doesn't achieve a lot more.
Yes it's a security measure.
Security against what? The user who owns the machine? Even assuming that it is technically feasible, is it a reasonable thing to do?
(These are rhetorical questions. I am posing them for you to think about, not because I either agree or disagree with what you are doing. And not because I want to debate this.)
1 - Suppose that the program runs as the user. First of all a user cannot transfer ownership of his files to another user. That would provide an easy way to "cheat" file usage accounting. Your encryption program running as the user couldn't do that either. (The OS cannot determine the intent of an operation.) Second, assuming an ordinary user could change the owner of a file, then after the change of ownership the user would not be able to read it. Moreover, neither could the encryption program.
So I read this question on Programmers SE and I got a little confused. In short, the solution is to keep all secret information in config files. Now this is where I'm confused. Couldn't a user just go searching for this file?
What methods are used to prevent users from finding the file? I'm using Java on Windows if that changes the answer at all.
I would think Encryption would come up but I'm not sure how that helps if the user can just decompile your source.
EDIT: To clarify further, my intention is to use API Keys (in this case 1, singular key) in an executable JAR file.
This depends what you are trying to achieve. I will assume here that the user has access to the enviroment in which your software is running. If you need to store some secret information, then you can use encryption, where the user has to supply a key. This is difficult to implement yourself correctly, but there are plenty of libraries and resources for this.
If your problem is exactly as described in the Programmers SE- you want to share code without sharing the 'secret' settings- extract the settings into a configuration file and don't share the configuration file. You can give a template, but with the secrets missing.
You can't really protect your informations if they are somehow available to the end-user - even if they are somehow crypted as long as your software is also available on the client. It only depends on the criminal energy the attacker will invest to get them.
One possibility could be to use ie. connection pooling for a database connect.
With this technique you get the connection object remote without the knowledge of the password - so you can use the connection within your app but the user cannot use informations to connect to the database with some sql tool.
See here for details: https://en.wikipedia.org/wiki/Connection_pool
Having read the link you provided I can think of the following below. Also please feel free to check the Security network (one interesting question here).
For a example in a database config file you could have an entry like
<%= ENV['USER_NAME'] %>
<%= ENV['PASSWORD'] %>
and those two variables are environment variables that you set.
Using encryption would be similar. You'd store an encrypted/hashed key in a config file and you use that data to see if there is a match when needed.
Encrypted data can be decrypted with a corresponding key
Cryptographically hashed data is very hard to crack
You'd need to design that appropriately whatever your requirements are.
And you can combine both methods too if you wish.
Example
I invite to have a look at my GitHub project's config folder. In particular the yaml files. I use the first method above mostly. It is a RoR project.
In my folder assets/data, there are a lot of XML files containing static data for my app.
It's really easy for someone to retrieve an APK, modify a part of it and install on a device.
I would like to prevent users to alter my static data by checking the integrity of my assets/data folder.
Initially I was considering to use MD5 checksum, but it will probably be too slow for the amount of files I gonna have (50-100).
Do you have any suggestion?
Edit:
This app is a game with an XML file describing each level.
I'll describe how you can effectively protect against modification and repackaging, not how you can protect the assets on their own, although you could ultimately apply the same technique to encrypting them. It's imperfect, but you can make modification significantly more difficult.
You sign the application with a certificate. Although they can remove yours, noone else can produce the same certificate when putting it back together. You can therefore check the signature of the application at runtime, to make sure it's what you expect.
Here's some cheap and nasty code to do this:
PackageManager pm = context.getPackageManager();
PackageInfo info = pm.getPackageInfo( context.getPackageName(), PackageManager.GET_SIGNATURES );
if ( info.signatures[ 0 ].toCharsString().equals( YOUR_SIGNATURE ) )
{
//signature is OK
}
where YOUR_SIGNATURE is a constant, obtained from running this code on the signed app.
Now, there are two remaining problems that you have already hinted at:
how can you stop someone just modifying the constant in the source code to match their certificate, then repackaging and re-signing the app?
how can you stop someone finding the check method and removing it?
Answer to both: you can't, not absolutely, but you can do a pretty good job through obfuscation. The free Proguard, but more usefully the commercial Dexguard, are tools for doing this. You may baulk at the current €350 cost of the latter; on the other hand, I have tried to reverse engineer apps that are protected like this, and unless the stakes were very high, it isn't worth the trouble.
To an extent, you could also do the obfuscation for (1) yourself; have the signature 'constant' assembled at runtime through some complicated programmatic method that makes it difficult to find and replace.
(2) is really a software design issue; making it sufficiently complicated or annoying to remove the check. Obfuscation just makes it more difficult to find in the first place.
As a further note, you might want to look at whether stuff like Google Licensing gives you any protection in this area. I don't have any experience of it though, so you're on your own there.
Sort of an answer although it is in the negative.
If the person has your apk and has decoded it, then even if you used a checksum, they can just update the code portion with the new checksum. I don't think you can win this one. You can put a great deal of effort into protecting it but if you assume somebody can obtain and modify the apk, then they can also undo the protection. On my commercial stuff, I just try to make the decoding non-obvious but not bullet proof. I know anything more is not worth the effort or even possible.
Perhaps you could zip up the xml files and put it in the assets/data folder; and then do a checksum on that .zip. On the first run, you could unzip the files to get the .xml layouts. See Unzip file from zip archive of multiple files using ZipFile class for unzipping an archive.
Probably the most reliable way would be for the level XML data to be downloaded from a server when the app is started with a check of the time stamp and sizes of the level files. That also lets you provide updates to level data over time. Of course this means you have the added expense of a server to host which may be another problem.
This question already has answers here:
Handling passwords used for auth in source code
(7 answers)
Closed 7 years ago.
I have to preface this question by saying that I'm aware that hard-coding a password in the client application is bad practice, for many reasons. There are other questions dealing with that issue. The scope of this question is narrower and assumes that authenticating credentials HAVE to reside on the client application's code for some set of reasons that are out of your control.
If some ways are better than others (for instance: JPasswordField stores the password in a char array instead of a String) and if you had to hard code it in the Java application, what measures could you take to make it harder to be fetched?
Update:
One instance of the application runs on a remote pc, where the end user has admin rights. The credentials are used to access a database in the same network, so the actual password is already predetermined and must be entered manually in the actual code.
.... if you had to hard code it in the Java application, what measures could you take to make it harder to be fetched?
For a start, I would make damn sure that the person with management responsibility for making this bad decision is fully aware that this is fundamentally and irredeemably insecure1.
Then I'd probably think up some naff algorithm that assembles the password in an obscure way; e.g. by building two byte arrays and XORing them together ... and distributing obfuscated bytecodes. The best you can hope to do is to make it difficult for folks with limited skills to reverse engineer the password from your code.
(Encrypting the password with a strong algorithm won't help much, because the choice of algorithm and the decryption key both have to be embedded in your code. Indeed, any scheme you can dream of can be defeated by using a debugger to set a breakpoint at the point where the password needs to be in the clear.)
1 ... and that even Jon Skeet wouldn't be able to make it secure.
If some ways are better than others (for instance: JPasswordField stores the password in a char array instead of a String) ...
I just want to note that the normal reasoning for using a char array to hold passwords in JPasswordField and the like is to protect against bad guys reading passwords out of core dumps or swap files. It won't really help in this case because we have to assume that the bad guy you should be worried about is simeone with system admin access. He or she will have sufficient control to attach a debugger to the JVM and capture the bytes from the char array.
As a general guideline you should never store the password (of course).
If you need to have a password available in runtime the best practice (as advocated in the Continous Delivery book by Jez Humble for example) is to provide the password at deploy/startup time. This way the password can reside only in peoples' heads instead of in an insecure file somewhere.
I do not know if this is feasible in your case, but you should aim towards that.
It's extremely unsafe to store sensitive data on the client side, espicially for password, because the .class files can be easily decompiled. Do you ever think about get some asymmetric encryption stuff involved ? Like public/private key pair or something like that?
I guess the least un-ideal solution is, if you can have challenge-based authentication protocol with random element in it.
That way it is not just the password, it is also the code which uses the password to generate correct responses, which needs to be reverse-engineered.
Then it can also be two-way authentication, that is your end can verify that the other side also uses same protocol/algorithm and also has same password.
And most importantly, then the password is never sent over network, so it can't be sniffed.
Diffie-Hellman key exchange is one widely used protocol for such a thing, but you could always roll your own simple implementation, if you only want obscurity, not real security. Well, real security is obviously out of your reach if everything can be decompiled and reverse-engineered from bytecode, but anyway... :)
I like Stephen's answer, but I would add...
Security of the source code is important too. No matter what method you use to obfuscate the password, anyone with access to the source can easily put a System.out.println(password) and capture the password where it's used, or run the code in debug and halt the code to inspect variables.
Even without compiling, anyone with access to the jar can start the java program in debug mode and halt the program where the password is used and inspect the variable, trivial with the source code, but still doable with just the jar and some tools.
You might consider having the program get the password from a secure server when it needs it (via a web service call or whatever) and have that server use a firewall to allow only certain IPs from accessing it (if the IP of the client machines is known). It still isn't secure, but at least it's something.
you can hash the password and even encrypt it if you wish. take a look at this post it might come useful. Java - encrypt / decrypt user name and password from a configuration file
I want to create a encrypted property file that stores information related to licences and some other highly sensitive data.
My Requirement during creation of encrypted Property file
Once created, should not be re-writable.
Once created nobody should be able to read the encrypted data.
After Creation, how I would be able to use the file in my project?
You can use the javax.crypto.Cipher[Input|Output]Stream for reading/writing your data; however, you will have to enforce the write-once functionality in your code... maybe be comparing the data with a SHA hash or something to ensure that it has not been changed.
I have run across opensource and commercial license managers for Java... you may want to search around so as not to reinvent the wheel.
Also, you will probably want to look into obfuscation tools at least for your sensitive API if you want to keep users from decompiling it.
Hope this helps.
Try: Jasypt library if it covers your usage scenario.
It provides an EncryptableProperties class for transparently managing and decrypting encrypted values in .properties file. It is also possible to integrate it into the configuration system of the Spring Framework.
Standard encryption in Java is pretty straight forward. I suggest checking out the reference guide for instructions on how to use the javax.crypto package. However I would urge you to reconsider your design if it requires sensitive data, stored on client machines, that you don't trust the users with. The reason I say that is in order for you program to access the information, it would need to have the encryption/decryption key stored internally which would mean that the key would be stored in the archive somewhere. In the best case, it'd be stored as a variable in one of the class files. Examining the binary classfile to determine this key would be trivial. At the very least you should consider obfuscating your encryption code to at least make it slightly more difficult to identify the key simply from examining the binary code or decompiling the class file.
See the answer to this other question:
Securing a password in a properties file
There, it was recommended the use of jasypt.
A Properties files is a human readable way to store a Map. If you don't want it to be be human readable, it doesn need to be a properties file.
One way to have a proeprties file with encrypted data is to encrypt the values of particular fields and use base 64 to turn them into text.