Secret Information in Programs - java

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.

Related

Java JCA - AES encryption, detecting if message was tampered with

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.

Methods for managing configuration files between multiple environments

Problem
We use java WAR files and keep config files in s3 buckets. Our environments: DEV,QA, Stage, and PROD each have their own config files and s3 buckets. If I add a new field, such as "Polling_RATE=5000", it must be manually added to each env because these config files also store passwords so they can not be tied to the application or kept inside Github. Not every engineer has access to each env so you must remember to inform the upper level engineers (DEVOPS) before the prod deployment date to add the new field for the application to work. Its a really messy process currently.
Question
Is there a utility or architectural design pattern meant to deal with this? How do you "version control" sensitive configuration fields that you can not store within github?
Recognizable problem.
Usually config fields with sensitive information like passwords change a lot less often than non-sensitive configuration fields. A possible solution is to split the config in two parts:
Config that's environment-specific but doesn't contain sensitive information. I would advise you to keep these files together with your source code and if possible, generate the files and automatically upload then to your configuration store (S3 in your case) at build time. They must be versioned and tied to the version of your application.
Config that contains sensitive information. Looking at the question, not all team members are allowed to read/write this information. You could store these in S3 with specific access rights so that only authorized members can access them. You would need a mechanism to join the files back together at deployment, or change the app to read from different config files.
However, this will only solve part of your problem. The ops guys will still need to perform changes when sensitive config keys change. Whether this is acceptable depends on how often sensitive config keys change.
An alternative to S3 could be to run a private Git repository (AWS's CodecCommit, for example). You'd have better version control and easier access for the devs to perform changes, since you're already using Git. You'll still have to fix the split access rights between dev and ops, or let that go (since DevOps is about trust and cooperation, that might be a good idea). You could apply a similar pattern here as I described above.
Another solution could be to move the configuration of sensitive values from property files to the system configuration. When you already use a provisioning system like Puppet or Chef, this will feel natural for the ops guys. Or set all sensitive values like passwords as environment variables and have the app read it as system properties.
Hope this helps!
We have been using dynamodb for keeping config values. The advantage with this approach is that the values are easily readable from console and validated.
Also another advantage is that we periodically check the values from dynamodb so if any value needs to be changed we just change it and the app automatically picks the new value instead of starting it again.
Sensitive values are stored encrypted using KMS keys and only the ec2 role that is running the application has right to decrypt using that Key.
We enhanced the Netflix archiaus project to fit our needs. May be you can check that out.

Bytecode injection countermeasures in jar files

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.

What's the most secure way to embed a password inside Java code? [duplicate]

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

how to create and use encrypted Property files in Java?

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.

Categories

Resources