I'm working on a simple java program that takes in user input, then parses the data and uploads it into a sql database to store online.
In my JDBC code I have the following: (Small example)
public class JDBCExample {
// JDBC driver name and database URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost/";
// Database credentials
static final String USER = "username";
static final String PASS = "password";
I am wondering how safe it is to have my username and password just openly available in plain text in my programming code after I convert it to a jar file. Is it easy to reverse engineer an application like this and reveal the code?
Incredibly easy, yes. javap -c JDBCExample.class will do it in a heartbeat.
Generally the way this is done is by separating the client-side app, which you distribute publicly, from a server-side app that runs on a trusted server. The client app you distribute doesn't access the database directly; instead, it talks to the server program, which publishes an API (often a RESTful API over HTTP) through which the client can make requests. That trusted server-side program is what talks to the database directly.
And even then, it's best practice to not hard-code your credentials into the server-side code. Instead, have the service read those credentials from a file which you keep separate from the code base (for instance, don't check that file into your source control).
You could save the username and password in a separate property file so that you could change it anytime without having to recompile the codes.
On your question, whatever your code can read in your codes/files, most likely, users can also. Please see this as reference.
I use ciphering and deciphering in my code.
use javax.crypto class to encrypt your password and inside your class use deciphering to decipher and send the password.
This works only if you place class file for deciphering rather than .java file.
example for ciphering link.
Related
I need jCrypt java class in my ColdFusion application to encrypt passwords. Here is the code that I'm trying to use:
<cfscript>
cfobject( name="JCrypt", type="java", action="create", class="JCrypt" );
enc_password = trim(JCrypt.crypt("kL","myPassTest123"));
</cfscript>
Once I run this code error occurred with this message:
Object Instantiation Exception.
Class not found: JCrypt
The message indicates that class is not found. I'm wondering how I can implement jCrypt in my ColdFusion application? Thank you.
I would be hesitant to use something like JCrypt that has little to no footprint on the Internet as the base for password encryption. The sourceforge page has a link to a homepage to no longer exists. You should be using BCrypt for password encryption.
https://auth0.com/blog/hashing-in-action-understanding-bcrypt/
Brad Wood has a great presentation on ColdFusion and BCrypt called "Pass the Salt".
You can download a copy of JBcrypt here:
https://www.mindrot.org/projects/jBCrypt/
Here's a ColdBox Module that can give you some idea of a CF implementation:
https://github.com/coldbox-modules/cbox-bcrypt
That repo has a copy of the JBcrypt.jar file and a CFC wrapper that you can just drop into your application.
https://github.com/coldbox-modules/cbox-bcrypt/blob/master/modules/bcrypt/models/BCrypt.cfc
This wrapper uses a Java Loader to to load the JAR if you can't just drop the file into the CF server's lib path.
oBcrypt = new path.to.Bcrypt();
password = "Password";
hashed = oBcrypt.hashPassword(password);
check = oBcrypt.checkPassword(password, hashed);
The hashPassword() function will save the salt and the encrypted password in a single string that you save in the database.
I am working on a project which have to access the MySQL database username and password to read and update the user database.
Initially i wrote the username and password of the database directly to my code.
But my teacher asked me to create a prompt box which will take the username and password on 1st run of the program and not again.
So if do that i will not be able to access the database next time.
I was thinking to store that username and password into a local text file.
Is it good idea.
Or there are any good methods to do this type of work?
You can store the information in a properties file (https://docs.oracle.com/javase/tutorial/essential/environment/properties.html), but should use encryption. See: How to encrypt String in Java
In your case, the best way will be storing in .properties file.
And after getting a user input => store to the properties file.
Also, good practice for storing passwords in DB is to use one-way hash. A variety of hash methods is good for this: MD5, SHA-256, etc.
However, it works only for one way. More info here - MD5 algorithm Decryption in java.
And in your case properties file should be enough.
Example for db.properties:
db.username=MyUser
db.password=MyPassword
You can have default values for connection. If user input doesn't match with it just print a warning message with something, like: "DB username or password is incorrect. Try again."
You can use something like JOptionPane for asking from user:
public void start() throws CreateDocumentConfigurationException {
// Custom button text
Object[] options = {"Yes, please", "Use default instead"};
int n = JOptionPane.showOptionDialog(null,
"Would you like to enter DB credentials?",
"DB Question", JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
estimateUserInput(n); // process result here. 0 - for entering new one, 1 - for using default
}
You can store the database login information in configuration file.
For Desktop Application,
.properties file can be use
For Web Based Application,
Store the password in context.xml of your Apache Tomcat Server.
I'm writing a small game in Java and I want to save user scores into a remote MySQL database. I'm using JDBC right now and I've got the connection working. I can insert and read as desired. The login credentials are hardcoded right now though:
public class DatabaseHandler {
private final String URL = "jdbc:mysql://_ip_goes_here_:3306/";
private final String DB_NAME = "db_name";
private final String USERNAME = "username";
private final String PASSWORD = "password";
//Rest of class
}
I can imagine that one could easily decompile the class file and extract this Information, thus gaining the ability to write into the database as they see fit.
Is there a better option to archive connection or would you use some kind of middleman between the .jar and the database? How would one realize this?
This kind of thing is where a properties file comes in handy. This page has examples on both reading and writing those, incidentally with the kind of parameters that you're dealing with:
http://www.mkyong.com/java/java-properties-file-examples/
Hopefully that amount of separation is sufficient for your needs.
Totaly agree with Brian - properties are not compiled into your .jar/.war/.ear - you can change them as you wish whenever necessary, that is the biggest plus of using them
I have created a basic log in page in Java that allows a user to log in successfully, however I have hard coded the username and password into the program. I would like to extend the program so it can accept multiple users from the XML File, as hard coding the details will be inefficient. This is the chunk of code that validates the log in details.
private void loginActionPerformed(java.awt.event.ActionEvent evt) {
if(username.getText().length()==0||password.getText().length()==0){
JOptionPane.showMessageDialog(null,"Mistake");
} else if (username.getText().trim().equals("admin")&& password.getText().equals("hello")){
JOptionPane.showMessageDialog(null, "Success));
}else {
JOptionPane.showMessageDialog(null, "Error");
}
}
This code only allows admin to log in as it is hard coded into the program.
Would the best solution to be to create a new class that reads the XML file and then create a object in the code above with the parameters username and password.
Keeping your users/passwords in an xml file will be an improvement over your actual code.
However, cipher (MD5?) the passwords to avoid having files in your disk whith pwds in plain text!
So you need to cipher also the passwords the users are introducing and then compare the cyphered codes, not the raw ones.
Typically this info is stored in an XML file or preferably in a database (which is also protected by its own access security policy)
The project i am working on have multiple instances(i.e different website) running in single code base. Based on the URL we show corresponding website.
For example, if http://www.uswebsite.com/ the we show US website. and ifhttp://www.cawebsite.com/ will show Canadian website. The code that is written to detect this is
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
String server` = httpRequest.getServerName();
If request is from the http://www.uswebsite.com/ then according to above code String server = uswebsite so we have additional code written to pop up the corresponding site
we are now planning to include the European instance in the same code base and i see that the URL for the europe site is going to be like this http://www.europewebsite.co.uk/. With getServer() as above will it fetch String server=europewebsite. By having the .co.uk at the end will the above code still get String server=europewebsite or String server=europewebsite.co Please advise as i can't test it out this in my local.
The wording of your question is rather confusing, so I'm assuming that you simply want to extract the hostname from a hierarchical URL string.
The most reliable way to do it is to construct an instance of java.net.URL or java.net.URI for the url string, and use the relevant getter to extract the hostname.
On the other hand, if you are trying to detect the virtual hostname for the current request in a servlet, then your httpRequest.getServerName() gives you that hostname as it appears in the first line of the HTTP request (unless something has rewritten it ...).
On the other hand, if you simply want to extract "europewebsite" from a DNS name like "www.europewebsite.co.uk", there is no general solution. I'd recommend converting the DNS to all lowercase and doing a lookup in a table that you have pre-initialized with all of the variations that you are prepared to recognize.
Normally httpRequest.getServerName() will return hostname, in your case it is complete name ie. "europewebsite.co.uk".