I've been looking at ftp and mysql connections (With passwords.) with java, and I'm wondering is this safe for distribution in software, I know that jar files can be opened and decompiled, is there anyway around using a plain text password, or is this not a problem.
You could create a PHP file for reading MySQL only.
You could give the file a GET parameter and the PHP script would check that it is only a SELECT query.
Then the PHP script would write the output from the SQL query to the file.
And in Java you could get the content via URLConnection or something like that.
I would create a service-based solution. Your java client can call the service to retrieve data.
That should give you the following benefits:
Your clients can be individually authenticated against the service.
The actual database implementation is hidden from the user and they don't need to even see the connection string.
The service defines approved functionality/queries. The user doesn't have direct access to the database to run arbitrary queries.
You can encrypt your passwords to secure them.
Here you have an example of how to use encryption/decryption: Encrypt and decrypt a String in java
Other link: How to encrypt String in Java
If your software can authenticate to your FTP server, anyone who has the software can access your service. This is how software works.
The only way to prevent this is to not give the person software that can authenticate to your FTP.
Related
Currently i am dealing with a conceptional issue in my Java - SFTP Client/Server - Setup.
Basically i got a client who sends files to a remote server and stores them there. BUT: You trigger the upload via a jar file on your computer, so anyone could decrypt the jar file and read the clear java file and obtain the credentials for my sftp.
Is there any technology to solve this issue or some workaround you can advise?
Greetings and Thanks!
It is inadvisable to put credentials into a common / shared JAR file. It can't be done securely, and if you need to get the user to replace them they need to download and install a new JAR.
There is no way that you can keep the credentials private from the user. If your credentials need to be used on the user's machine, then it will be possible for the user to extract them, somehow. No matter what you try. (Assuming that they control their machine ....)
Saving credentials encrypted does not protect them from the user. The application needs the decryption key. The user can find / extract that and then recover the credentials.
It is better to issue distinct upload credentials for each user. That way, if one user loses or abuses his credentials you can invalidate them without affecting other users.
If I'm understanding your issue correctly, it is rooted at the fact that your java sources contain your credentials.
First, I highly recommend using jSch library for a great implementation of SSH2.
Regarding your credentials, you can find your answer here.
In short - save your credentials encrypted.
Where should I store credentials for my java application to access third party services?
The credentials are not specific per user on my application. They are for accessing a web service my application is consuming. I know enough not to hard code them into my application, but where and how do I store them? I also assume they will need to be encrypted.
.jar file is best way to store all credentials.
Create interface where store your credentials as a final String
convert interface to jar file
Add that jar file in your build path
Implement this interface where u use credentials, and access String object in which u stored credentials.
Db
.properties file
configuration class with constant
Spring have nice functionality with #Value annotation that can auto-magically inject value from .properties file (under resources folder) with a given key.
I use that because in my case I have different key values in multiple app instances and db would require little more complexity, and furthermore I don't make unnecessary queries to db.
On security basis if attacker can read files on your server than he can easily read your db so that don't play a part here. It can be stored in any file on the system.
On the other hand you can have configuration class with
public static final String SECRET_KEY = "someKey"
To build upon #Zildyan's answer, comments and references to other answers.
There are a few options for where to store:
Database
Properties file
Constant (hard coded)
File system (away from application)
As for how to store:
Depending upon sensitivity. Credentials could be stored in plain text (low sensitivity) or should be encrypted (high sensitivity).
It should also be noted that using a combination of encryption and separating the credentials from the source you would restrict internal access to the credentials.
Some examples
a password stored in plain text may be added to source control and read by anyone with access to the source control.
An encrypted password with decryption code would be easily available to anyone able to run the code.
A plain text file stored on the server may be accessible to anyone with access to the server.
An encrypted file stored on the file system may only be accessible to sys admins and the decryption method available to devs.
The same goes for storing in a database and who has access to that database.
JNDI
Per Wikipedia:
The Java Naming and Directory Interface (JNDI) is a Java API for a directory service that allows Java software clients to discover and look up data and resources (in the form of Java objects) via a name.
Your enterprise likely has a JNDI-compatible directory service established. You would ask the sysadmin to include an entry for your particular credentials.
If you are self-administering, then your Java EE (now Jakarta EE) should have a JNDI-compatible server built-in. Learn to configure it, and add the entry for your particular credentials.
I'm looking for a way to open a JDBC connection without specifying my database login and password in plain text, as the application will be distributed and any Java decompiler would reveal them, allowing the users to access the database easily.
Is there any way to encrypt them, or store them somewhere else?
Looks like you want to let Android application talk to your database directly? Don't do that. It's a major security flaw. No matter how you encrypt your credential, you have to reveal your plain text somewhere during the execution of the program, and anyone with a debugger can see that. The correct way is to have use an API on your web service and call that API from client. All database transaction should happen in a trusted intranet.
Why would you want to do this? Generally the business side of your application would have this info and connect to MySQL. There, a user does not have access to any code. Then you create an endpoint that actually is accessible to the public. There you can worry about passing username and password stuff to the business logic, which again, actually has direct access to your database.
Basically, do not open a jdbc connection anywhere but your server side. Its a security measure.
Problem Description
I am writing application for Android. Application must do following:
Connect to the server using following URL:
http://www.example.com/database.xml?username=xxx&password=xxx
username and password I must keep in the phone and this username and password are same for the all users. For example if 1.000.000 people have my application they all connect to the server using same url same username and password.
Download database.xml file from URL and save data in the SQLite database.
Issues
How I can use URL in my application to be sure that users which have access to my codes can't know from the code which URL I use and also to keep secure my password and username.
Or even just to keep whole URL secure http://www.example.com/database.xml?username=xxx&password=xxx as it is same for all users.
How I can protect my SQLite database. For example if somebody has root access on the phone he can get database open it and get all information which I keep there.
I need to protect my data.
I think you should go for ProGuard. I know its very hard to prevent from reverse-engineering. Following are some post which give some knowledge about this.
How to avoid reverse engineering of an APK file?
Is it really impossible to protect Android apps from reverse engineering?
Protecting Your Android Applications is an article which describes necessary information about ProGuard.
Read FAQ to know more.
To protect database, use SQLCipher.
use HttpRequest apis to get the data instead of using browser intent.
In your case I don't see any perfect protection engineering. Any one with a primary reverse engineering knowledge can get the data from your code.
I have a plain Java application which is supposed to connect to the database. I don't want to store database connection url and username/password in a properties file or hardcode it in application. What is a common way to solve this problem? How a Java application can connect to database without revealing username/password?
I'm a .NET dev, but I've run into the exact same situation.
Last year I was working at a company that had to be PCI compliant to store credit card data, so security was a big deal. The URL/login data has to exist somewhere. The most common method I've seen for securing it is with encryption. I don't know about Java in particular, but .NET has several encryption namespaces in the core Framework. We used these to encrypt the database logins.
You still have a potential security vulnerability, which are the encryption keys used to encrypt/decrypt the data. We used the PCI "compensating controls" method here. Access to the keys is restricted to "key management" role. We also tracked access of the key itself so that there was a record of all user-initiated and system-initiated access. No one user had access to these logs, so there could be no covering of tracks by a single user. These overlapping security methods essentially create a situation where nothing less than a coordiated conspiracy between multiple administrators is required to put the data in jeopardy.
If you aren't willing to store it, you have to prompt for it. You could encrypt the password, but then you have to have a key to decrypt it and you are stuck in the same problem.
One of the common solutions to this problem for server based applications is to store the username and password in a file that has user permissions set in such a way that only the executing user of the application/service can read its contents.
For example, you run your application as user foo-service and it inherits all of the access privileges of the foo-service user. The file containing the username and password is only readable by that user. You read the value from the file and connect to the database as normal.
Possible problems with this approach:
The superuser of this machine may be able to get the password to the database.
An attacker who has penetrated your application security can get access to the database credentials.
The above problems are normally mitigated by tuning the access privileges for the application to the database and the network. Nearly any other solution you come up will get you into a chicken-and-egg problem because you are basically trying to hide something from itself.
The best way would be to store the information as a configured data source in the JNDI context of your application server. You can then use the facilities of the application server to configure data sources at deployment time. All the application has to do is look up the appropriate JNDI name at runtime and use that. This is a common pattern for Java web applications.
Use web services to separate your application from the server doing the database access. Sign your web application and then only allow a properly signed application to call the web services server.
You can try to load a file using system properties.
-Dapplication.configuration=application.properties.
When the property file is not passed then the you should use default file with default config.
When the file exists you override the defaults with the values provided from configuration.
java -Dlog4j.configuration=file:/log4j.properties -Dapplication.configuration=file:/live-conf.conf -jar app.jar "applicationarg1" "applicationarg1"
More sources to follow:
https://docs.oracle.com/javase/tutorial/essential/environment/properties.html
How to override system properties:
-Dproperty=value
Set a system property value. If value is a string that contains spaces, you must enclose the string in double quotes:
http://docs.oracle.com/javase/6/docs/technotes/tools/windows/java.html