Every example I see says to use a strong password but then they just slap it in the source code. That doens't seem quite right to me.
Is it possible to authenticate to the keystore as the current account so no passwords are involved?
If that's not possible, I have a requirement to not store passwords in source code, which is perfectly acceptable, but it seems like at some point a password needs to be a part of the equation, can someone point me to the most secure way to handle this?
I'm tempted to add the password as part of the build, but then I have a plaintext password on the build server, which almost seems roughly the same to me.
First, the general rule: If you ship software which, all by itself, is able to unlock some 'secure store' (so, without involvment of a server under your control or some other hardware under your control)... it is impossible to hide this information from the owner of the computer it runs on.
Example: Webbrowsers tend to have a feature to offer storing website passwords. These passwords are stored in files, and with the right tools you can open these files and see the passwords plain as day. There is no way to fix that with more software or more cryptographic algorithms. The only solution is to make the software incapable of unlocking said datastore, for example by requiring that the user enter a master password every time they wanna look into it, or putting some sort of secure enclave into the hardware and having THAT take care of the crypto. Java generally does not have the right libraries to interact with such hardware (apple's T2 is a very advanced take on this concept; TPM chips are a budget option).
So, once you're okay with that, you can still go: Okay, well, I do NOT want the authentication keys in the source code; in order to build a production distributable from the sources, the builder will have to supply it. To accomplish that:
(Assuming maven style project structure):
Make file src/main/resources/com/yourcompany/yourproject/keys/KeyFile.txt and then update your .gitignore file to ignore that, by putting /src/main/resources/com/yourcompany/yourproject/keys/KeyFile.txt in there.
Write the key in this file. Share this file with some secure means with all members of the project who should have it.
Write code: In src/main/java/com/yourcompany/yourproject/keys/ProjectKey.java have a static method to retrieve the key. It would look something like this:
public final class ProjectKey {
/* prevent instantiation */ private ProjectKey(){}
private static final String PROJECT_KEY = loadKey();
public static String getKey () {
if (PROJECT_KEY != null) return PROJECT_KEY;
throw new IllegalStateException(
"Key file not present; find somebody with the file and place in: " +
"src/main/resources/java/com/yourcompany/yourproject/keys/KeyFile.txt");
}
private static String loadKey() {
InputStream in = ProjectKey.class.getResourceAsStream("KeyFile.txt");
try {
return in == null ? null : new Scanner(in, "UTF-8").next();
} finally {
if (in != null) in.close();
}
}
}
Make a dir in your project called 'keys' or whatnot. In your .gitignore file at the root, put the line /keys in order to ensure these do not go into source control.
You'd have to mess around with some build tool plugins if you want builds to fail if the file is missing. Also, you'd have to update the scanner's delimiter if the 'key' contains any whitespace (I'm using scanner here as the fastest way to turn an inputstream into a complete string; if you have for example Guava, it has better calls to do that, and you should use those).
Related
I want to be able to create a file that'll act like a zip but at the same time it isn't an actual zip.
Let's say I have a program that'll take a bunch of files and directories and store them into a single file with a name and extention of data.rds and you would need the same program to extract them out of it. I've seen in lots of different games that they use file formats such as .arc, .nsa, .mxdl etc which all store many files inside of them, .rar is probably the most commonly known format. The four extentions can't be opened as a normal zip and require a specific program in order to extract the files from them, I want to learn as to how you would encrypt and decrypt many files into a single one without making it readable like it would be in a normal zip file.
Pretty much how would one go about doing this? I know it would be a long process and won't be answered with a few simple lines of code but if someone could point me in a direction towards learning as to how to do such a thing, that would help helpful.
No matter what format you invent, someone will figure it out. Anyone can decompile your code and see your algorithm.
I would just use the Zip format and give the file a different extension (which it sounds like you're already doing). An easy way to keep casual observers from opening your file is to put a couple junk bytes at the front of it:
private static final byte[] secretSignature = { 10, 20 };
void writeData(Path file)
throws IOException {
try (OutputStream out = new BufferedOutputStream(
Files.newOutputStream(file))) {
out.write(secretSignature);
ZipOutputStream zip = new ZipOutputStream(out);
// Write zip entries
zip.finish();
}
}
void readData(Path file)
throws IOException {
try (InputStream in = new BufferedInputStream(
Files.newInputStream(file))) {
in.skip(secretSignature.length);
ZipInputStream zip = new ZipInputStream(in);
ZipEntry entry;
while ((entry = zip.getNextEntry()) != null) {
// Read entry
}
}
}
You could approach it like this:
1) start with an application that does "simply" store the contents of directories, list of files, ... in a single file. Meaning: learn how to collect all these files; and how to push them into a single uncompressed archive (and of course: ensure that you can extract things afterwards again)
2) when that step is working (and properly and extensively tested); then add a "compression" resp. "decompression" step.
Your favorite search engine will give you many results when searching for "compression algorithms".
It depends on your goal.
I'm going to assume you wish to write your own algorithm for fun.
If you just want to pack things together and encrypt them, well, just take the files you need and write their binary content in a sequential manner, prepending at the start of the file something like an index table, that tells you where in the big-file each file starts. Then encrypt everything using your algorithm of choice.
If you want to also compress them, the simplest algorithm I feel suggesting you to implement is Huffman encoding of your binary content. Note that, while simple enough in theory, it can still be quite an ordeal to implement, so think carefully if it's worth it or if you can rely on something off-the-shelf.
Bottom line: if you are doing it to teach yourself something, go for it. If you need it in a bigger project where the end goal isn't learning these things, just take something that already exists.
I sense that you are more concerned about authenticity, that is, that the archive is not modified. I will further assume that you don't really want to implement your own compression algorithms.
That being said, what you could is the following:
Create a zip with different extension.
Compute the SHA1 hash of the file
Use the SHA1 hash to check if that archive hasn't been changed.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I want to make an desktop application that only runs on machines that have key or licence.
How this can be achieved?
This depends entirely on how secure you want to make it...
The problem with Java is that you can reverse compile it. So if someone wanted to, they could download your software, reverse compile it, and then remove whatever security you have put in place (and then redistribute it if they wanted).
This is only a problem if you plan on going mass market and selling it and piracy would actually be a problem though.
If you're not concerned about this, then you can either go for online, or offline checking.
The company I work with uses the online method; there are a few steps:
EDIT: I've since changed how this works, as the old way was a maintenance nightmare.
A license file
(this can contain whatever you want in reality, it just has to be unique per user. Most people normally go with general garb;
name
company
email
and then a key. i.e. the JDU8-AJS9-88DF-SASF-ASF9 kind of thing you often see.
The program generates a hash from the license file.
put all the data from the license file into a string
pass the string to a hashing function this page can show you how.
have the program check online (on your server). The data gets encoded in an HTML request (post/get/json/whatever you want) and submitted to your license verification page, which then verifies the data. Included in the data is a randomly generated string, which is used by the verification page to generate another password. This is then returned to the program, which has also used the random string to generate its own password. If the two match, the program starts up.
To generate the keys, just use the same hashing function, and then upload the hash to your server.
If you want it to be offline, you could include the hashes in the code I guess and check against them there.
I should point out, however, that I'm not a security expert by any means, I just develop for a company as a portion of a Ph.D. and this is just how I did it.
Edit: this image might be helpful:
Second Edit:
I have now included "offline verification" in the process. It's not really offline verification, it just uses the user as a proxy - they need to access the internet another way.
it works like this:
no internet connection found: supply the user with a 4 digit code
user goes to offline verification page (optimized for mobile use too)
user selects which software they use from the dropdown list
user enters their username (this field remembers entries)
user enters the code the program gave them and submits
webpage provides a 4 digit code, which they then enter into the program, and it starts.
program adds some special data to the license file meaning that this process won't need to be repeated for the next week/month/however long.
every time the program successfully verifies online, it also adds an offline access password to the license file, which means it's robust against temporary internet downtime, and will only stop working if the internet is down for more than a week/month/however long it's set up to work for.
You can track licencing of a machine with macIP on online . Even in windows you can write in registry there is no api but still you can do it. Find snippet bellow to read registry -
public static final String readRegistry(String location, String key){
try {
// Run reg query, then read output with StreamReader (internal class)
Process process = Runtime.getRuntime().exec("reg query " +
'"'+ location + "\" /v " + key);
StreamReader reader = new StreamReader(process.getInputStream());
reader.start();
process.waitFor();
reader.join();
String output = reader.getResult();
// Output has the following format:
// \n<Version information>\n\n<key>\t<registry type>\t<value>
if( ! output.contains("\t")){
return null;
}
// Parse out the value
String[] parsed = output.split("\t");
return parsed[parsed.length-1];
}
catch (Exception e) {
return null;
}
}
And in class level if you want to obfuscate use proGuard .
it depends how many customer you plan to have and the distribution mode also. You may use a licence server but this require an internet connection for the customer. You can also use USB dongles to manage licencing.
There are no perfect system you need to make a comproise between simplicity, effort and price.
Android's security manual says that it is not safe to keep public key (used for Android market) just as a string and it should be hidden/encoded somehow.
Can somebody please provide me with example how it can be done?
(I don't have separate server, so it can not be stored there)
Upd. Believe, this is quite common task related not to Android, but to other apps also.
The relevant text from the page you linked to is this:
Important: To keep your public key safe from malicious users and
hackers, do not embed your public key as an entire literal string.
Instead, construct the string at runtime from pieces or use bit
manipulation (for example, XOR with some other string) to hide the
actual key. The key itself is not secret information, but you do not
want to make it easy for a hacker or malicious user to replace the
public key with another key.
That's pretty much all you need to know. There's no harm in people knowing your public key, the potential harm here is that someone replaces the public key in your program with their own in an effort to divert in-app purchases to their own account.
They're suggesting that you make it more difficult for that attacker by storing the key in separate pieces or XORing the key with some other string. Now, instead of just pasting their key over yours, they have to figure out what transforms you're doing to the string and make their own key fit that pattern. This is more work and might deter casual attackers, but won't prevent someone who is really determined.
If you use the Keytool utility this is all done for you. You'll get a .keystore file on your local computer containing your private key(s) that is encrypted with a password; keep that file and the password secret and you're secure.
http://developer.android.com/guide/publishing/app-signing.html
In fact I believe the Android plugin for Eclipse even does all of this for you automatically.
On the public key, you can hash it and save it as a hash value. Better yet would be to salt the hash value with something you would know when you need to get the hashed value back. May be something like user name, or ESN. Look at android.telephony.TelephonyManager.getDeviceId()
We have to monitor the change on a remote system file, that we acces throught FTP, SMB.
We do not have any SSH access to the remote system / os. Our only view of the remote system is what FTP or Samba let us see.
What we do today :
periodicly scan the whole directory, construct a representation in memory for doing our stuff, and then merge it with what we have in database.
What we would like to do :
Being able to determine if the directory have change, and thus if a parsing is needed. Ideally, never have to do a full parsing. We dont want to rely too much on the OS capability ( inodes... )because it could change from a installation to another.
Main Goal : This process begin to be slow when the amount of data is very large. Only a few % of this date is new and need to be parsed. How parse and add to our database only this part ?
The leads we discuss at this moment :
Checking the size of folder
using checksum on file
Checking the last date of modification of folder / file
What we really want :
Some input and best practice, because this problem seams pretty commons, and should have bean already discussed, and we dont want to end up doing something overly complicated on this point.
Thanks in advance, a bunch of fellow developpers ;-)
We use a java/spring/hibernate stack, but i dont think that matters much here.
Edit : basicly, we acces a FTP server or equivalent. A local copy is not a option, since the amount of data is way to large.
The Remote Directory Poller for Java (rdp4j) library can help you out with polling your FTP location and notify you with the following events: file Added/Removed/Modified in a directory. It uses the lastModified date for each file in the directory and compares them with previous poll.
See complete User Guide, which contains implementations of the FtpDirectory and MyListener in below quick tutorial of the API:
package example
import java.util.concurrent.TimeUnit;
import com.github.drapostolos.rdp4j.DirectoryPoller;
import com.github.drapostolos.rdp4j.spi.PolledDirectory;
public class FtpExample {
public static void main(String[] args) throws Exception {
String host = "ftp.mozilla.org";
String workingDirectory = "pub/addons";
String username = "anonymous";
String password = "anonymous";
PolledDirectory polledDirectory = new FtpDirectory(host, workingDirectory, username, password);
DirectoryPoller dp = DirectoryPoller.newBuilder()
.addPolledDirectory(polledDirectory)
.addListener(new MyListener())
.setPollingInterval(10, TimeUnit.MINUTES)
.start();
TimeUnit.HOURS.sleep(2);
dp.stop();
}
}
You cannot use directory sizes or modification dates to tell if subdirectories have changed. Full stop. At a minimum you have to do a full directory listing of the whole tree.
You may be able to avoid reading file contents if you are satisified you can rely on the combination of the modification date and time.
My suggestion is use off-the-shelf software to create a local clone (e.g. rsync, robocopy) then do the comparison/parse on the local clone. The question "is it updated" is then a question for rsync to answer.
As previously mentioned, there is no way you can track directories via FTP or SMB. What you can do is to list all files on the remote server and construct a snapshot that contains:
for file: name, size and modification date,
for directory: name and latest modification date among its contents,
Using this information you will be able to determine which directories need to be looked into and which files need to be transferred.
The safe and portable solution is to use a strong hash/checksum such as SHA1 or (preferably) SHA512. The hash can be mapped to whatever representation you want to compute and store. You can use the following recursive recipe (adapted from the Git version control system):
The hash of a file is the hash of its contents, disregarding the name;
to hash a directory, consider it as a sorted list of filename-hash pairs in a textual representation and hash that.
Maybe prepend f to every file and d to every directory representation before hashing.
You could also put the directory under version control using Git (or Mercurial, or whatever you like), periodically git add everything in it, use git status to find out what was updated, and git commit the changes.
I am currently writing a program which takes user input and creates rows of a comma delimited .csv file. I am in need of a way to save this data in a way in which users are not able to easily edit this data. It does not need to be super secure, just enough so that it couldn't accidentally be edited. I also need another file (or the same file?) created to then be easily accessible (in the file system) by the user so that they may then email this file to a system admin who can then open the .csv file. I could provide this second person with a conversion program if necessary.
The file I save data in and the file to be sent can be two different files if there are any advantages to this. I was currently considering just using a file with a weird file extension, but saving it as a text file so that the user will only be able to open it if they know to try that. The other option being some sort of encryption, but I'm not sure if this is necessary and even if it was where I would start.
Thanks for the help :)
Edit: This file is meant to store the actual data being entered. Currently the data is being gathered on paper forms which are then sent to the admin to manually enter all of the data. This little app is meant to have someone else enter the data from the paper form and then tell them if they've entered it all correctly. After they've entered it all they then need to send the data to the admin. It would be preferable if the sending was handled automatically, but this app needs to be very simple and low budget and I don't want an internet connection to be a requirement.
You could store your data in a serializable object and save that. It would resist casual editing and be very simple to read and write from your app. This page should get you started: http://java.sun.com/developer/technicalArticles/Programming/serialization/
From your question, I am guessing that the uneditable file's purpose is to store some kind of system config and you don't want it to get messed up easily. From your own suggestions, it seems that even knowing that the file has been edited would help you, since you can then avoid using it. If that is the case, then you can use simple checks, such as save the total number of characters in the line as the first or last comma delimited value. Then, before you use the file, you just run a small validation code on it to verify that the file is indeed unaltered.
Another approach may just be to use a ZIP (file) of a "plain text format" (CSV, XML, other serialization method, etc) and, optionally, utilize a well-known (to you) password.
This approach could be used with other stream/package types: the idea behind using a ZIP (as opposed to an object serializer directly) is so that one can open/inspect/modify said data/file(s) easily without special program support. This may or may not be a benefit and using a password may or may not even be required, see below.
Some advantages of using a ZIP (or CAB):
The ability for multiple resources (aids in extensibility)
The ability to save the actual data in a "text format" (XML, perhaps)
Maintain competitive file-sizes for "common data"
Re-use existing tooling support (also get checksum validation for free!)
Additionally, using a non-ZIP file extension will prevent most users from casually associating the file (a similar approach to what is presented in the original post, but subtly different because the ZIP format itself is not "plain text") with the ZIP format and being able to open it. A number of modern Microsoft formats utilize the fact that the file-extension plays an important role and use CAB (and sometimes ZIP) formats as the container format for the document. That is, an ".XSN" or ".WSP" or ".gadget" file can be opened with a tool like 7-zip, but are generally only done so by developers who are "in the know". Also, just consider ".WAR" and ".JAR" files as other examples of this approach, since this is Java we're in.
Traditional ZIP passwords are not secure, and more-so is using a static password embedded in the program. However, if this is just a deterrent (e.g. not for "security") then those issues are not important. Coupled with an "un-associated" file-type/extension, I believe this offers the protection asked for in the question while remaining flexible. It may be possible to entirely drop the password usage and still prevent "accidental modifications" just by using a ZIP (or other) container format, depending upon requirement/desires.
Happy coding.
Can you set file permissions to make it read-only?
Other than doing a binary output file, the file system that Windows runs (I know for sure it works from XP through x64 Windows 7) has a little trick that you can use to hide data from anyone simply perusing through your files:
Append your output and input files with a colon and then an arbitrary value, eg if your filename is "data.csv", make it instead "data.csv:42". Any existing or non-existing file can be appended to to access a whole hidden area (and every file for every value after the colon is distinct, so "data.csv:42" != "data.csv:carrots" != "second.csv:carrots").
If this file doesn't exist, it will be created and initialized to have 0 bytes of data with it. If you open up the file in Notepad you will indeed see that it holds exactly the data it held before writing to the :42 file, no more, no less, but in reality subsequent data read from this "data.csv:42" file will persist. This makes it a perfect place to hide data from any annoying user!
Caveats: If you delete "data.csv", all associated hidden data will be deleted too. Also, there are indeed programs that will find these files, but if your user goes through all that trouble to manually edit some csv file, I say let them.
I also have no idea if this will work on other platforms, I've never thought to try it.