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.
Related
In the past many applications have stored Temporary files in the Temp/Tmp directory; either the System's or the user specific ones. Recently though we've had many users in Enterprises where usage of the Temp directories are blocked due to Virus Scanning tools or Host Intrusion Prevention Tools and policies not allowing usage of those locations. I think the fear here is that multiple applications can read and write from that location and so a rogue application could negatively affect another application or its temporarily stored data. This seems like a correct and more secure way to function, so I cannot ask that people begin allowing an increased risk.
My question then is How/Where to (physically) securely store User Specific, Application Specific, yet temporary files.
Should each application be expected to manage this themselves, or is there some new Application & User Sandboxed Temporary data store feature I am not aware of?
Specifically I am focused on using .NET 4.0+, C#, and Windows 7+, but the question should be applicable to other languages used on Windows as well.
Similar, but older and not specific enough threads
C# Best Practices: Writing "temporary" files for download: Place in applicaion's environment folder or temp folder
Virus scanners locking and deleting temporary files - best way to cope with them?
Windows temp directory details (Java)
https://stackoverflow.com/questions/30547113/secure-temp-file-creation-within-temp-directory
The 1 answer of Encrypting the contents and file name does not seem like a Best Practice solution, and will still be blocked by the Host Intrusion Prevention System.
You should use the special folder typically referred to as AppData. This can be accessed in C# by calling Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).
The description of ApplicationData is as follows on MSDN:
The directory that serves as a common repository for application-specific data for the current roaming user.
I have created a number of applications for financial services clients (i.e. highly restricted and locked down corporate desktop environments) that use this location and have not had any issues with creating temporary files there.
MSDN: Environment.SpecialFolder
The ApplicationData directory is indeed the right place according to MS guidelines to store app specific files, including temp files. However this doesn't necessarily solve your security problem. Whether or not it solves it depends on what the problem is.
Windows uses ACLs to grant/restrict permissions to file system directories. ACLs are specific to a user, a group, or a set of users/groups. There are not specific to applications. Suppose a particular user, Art, runs an app, Papp, and Papp stores its data in C:\Users\Art\AppData\Roaming\Papp. If Art runs Qapp then Qapp (unless run as a different user) has access to Papp's files.
Note that by default the environment variables TMP and TEMP are under AppData, so in security terms the ApplicationData special folder is no better or worse. (It is better than C:\temp and c:\tmp though).
If user Betty runs Qapp then by default Qapp won't have access to Art's Papp files if they are under his AppData. So if the security problem is to prevent other users running Qapp from accessing Art's Papp files then any directory under AppData will work.
But if the problem is with Art running Qapp (which could be malware and could be something Art didn't intentionally run), then some solutions are:
1) Use a white list program that only allows authorized programs to run, 2) Use a black list program (ie traditional anti-virus) that attempts to stop malicious programs like Qapp 3) hybrid approach where trusted programs runs as Art and untrusted programs runs as another, less privileged user or run in a sandbox.
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.
I have a jnlp application that loads and executes a jar file ( client ) on a users computer. The user uses this jar to communicate with a server that provides a services. I've seen users using javassit and javasnoop to alter the functionality of the client. Is there any way I can remotelly detect changes created by the previously mentionted utilities ? For example, can I checksum the classes locally and send the result to the server ( who knows the correct checksum of each class ) ?
There is no way in general to prevent the client from running any code they wish to. The security of your system should never rely on assuming that clients are running specific code or are not aware of specific information contained in the jars you send them.
Furthermore, attempts to impose DRM tend to cause problems for legitimate users and alienate your customers while doing little to prevent people who actually do want to hack the system.
You can for example create a check sum of your java file and make your application to calculate the checksum at runtime and send it for verification to server. The simplest checksum is a hash code of whole jar.
The only question is why? And who is the super user that takes your jar and performs instrumentation on it? And why is he doing this? And even if he has reasons, who cares? If you are afraid that somebody is going to hack your server make it secure enough and do not care about client (IMHO).
You can open a classfile named p1.p2.ClName with Classloader.getResourceAsStream("/p1/p2/ClName.class"), read it, and compute its checksum.
But, as user can change the functionality, he can also remove that checksum checking.
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've been searching for days but I have not found a clear answer. How would I go about writing a small jar file to give to my users that simply gets a jar file from a URL (with multiple classes in it) and run it. It would be great if the end user never actually has the jar on his computer at anytime. I am doing this as a small security measure.
If the user is going to execute your code, it must exist on their computer. It's just the way it works.
If you wanted to re-write your code to perform most of the work on your servers, that'd be one mechanism to combat piracy, but it does mean that you need to duplicate all the input verification checks: perform them once on the client side, for reasonable response time, and again on your own servers, to ensure that your users aren't trying to use your services improperly.
Another mechanism would be to run a VNC server on your servers, and ask your users to VNC in. The software executes completely on your servers. It is a draconian step though, one your users will likely detest.
I am not sure how you'd go about it, but I know that using Maven allows you to access things without having the jar locally. You can just specify the URL. So maybe look into how they do their repositories.
Another option would be to encrypt your JAR file and write a custom class loader that decrypts it on the fly on client machines. This won't prevent a power user from attaching a debugger to the JVM and examining your byte code, but it prevents the typical user from having access to your code.