2

I am trying to learn how you would tackle the task of creating a Java console application, connect to a (in this case) MySQL DB and send or retrieve data, without showing your username and password in the source code of the Java application. I currently have no trouble creating a connection showing credentials.

// JDBC driver name and database URL
    private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
    private static final String DB_URL = "jdbc:mysql://192.168.1.159:3306/javahelper";

//  Database credentials
    private static final String USER = "xxxx";
    private static final String PASS = "RandomString";

    /**
     * @return
     */
    public Connection openConnection() {
        Connection connection = null;

        try {
            Class.forName(JDBC_DRIVER);

//          opening connection
            connection = (Connection) DriverManager.getConnection(DB_URL,USER,PASS);

        } catch (ClassNotFoundException e) {
            System.out.println("This is from openConnection method");
            e.printStackTrace();
        } catch (SQLException f) {
            System.out.println("This is from openConnection method");
            f.printStackTrace();
        }

        return connection;
    }

From what information I can gather you always need to show your credentials somewhere in the application. But how do you than achieve "safe" connection between a application and a DB, so others can't misuse your credentials for malicious reasons?

6
  • 1
    You can use property file. (also recommanded) and you can manage rights on that file as you wish. Refer this link : docs.oracle.com/javase/tutorial/essential/environment/… Commented Dec 30, 2014 at 12:29
  • store it in properties file by encrypting the password and decrypt it in code. Also make sure that properties file are read protected by others. Commented Dec 30, 2014 at 12:42
  • Thanks @VishalZanzrukia I Googled properties file and read that its a normal text file, where you read the content through a inputStream, with a syntax of "key=value". But how do you manage permissions to this file to the application only? Edit: I find this article interesting, but dont know if its still valid since its from 2008 owasp.org/index.php/How_to_encrypt_a_properties_file Commented Dec 30, 2014 at 13:03
  • Thanks @Almasshaikh Isint it possible to send the password in a hashed form to the DB and check it their if its correct? Isint it possible to debug / decompile the program and get the password if you decrypt it in the program itself? Commented Dec 30, 2014 at 13:05
  • No if you decompile the code you wont get it. Yes if you are debugging it, you might get it. But there are ways to avoid that.. Commented Dec 30, 2014 at 13:11

3 Answers 3

3

one way of doing it is using a properties file having your credentials or having your data in a xml file.

create a properties file like the one below

// database.properties
DB_URL=jdbc:mysql://localhost:3306/UserDB
DB_USERNAME=user_name
DB_PASSWORD=password

Use this information in your code to get the username and passwords.

Properties properties= new Properties();
FileInputStream input = null;

try{

input = new FileInputStream("database.properties");
props.load(input );
con = DriverManager.getConnection(props.getProperty("DB_URL"),props.getProperty("DB_USERNAME"),props.getProperty("DB_PASSWORD"));

}
Sign up to request clarification or add additional context in comments.

Comments

1

you can use encrypt the username and password.The best opensource encryptor(My personal view) is jbcrypt

// Hash a password for the first time
String hashed = BCrypt.hashpw(password, BCrypt.gensalt());

// gensalt's log_rounds parameter determines the complexity
// the work factor is 2**log_rounds, and the default is 10
String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12));

// Check that an unencrypted password matches one that has
// previously been hashed
if (BCrypt.checkpw(candidate, hashed))
    System.out.println("It matches");
else
    System.out.println("It does not match");

3 Comments

I might be missing something, but couldnt everyone decrypt it then since it is an opensource library and its a known library? Im really wondering
@codequestioneer Most encryption algorithms are public and known. That is not a problem (on the contrary: it is a must for good security that others can scrutinize the algorithm); you just need to make sure that the password is not available to others.
How would you use this in conjunction with authentication against a MySQL service?
1

Sharing what i find

Creating and using the propertise file

I created a database.properties file(normal text file) and placed it in the src folder of the Java project.

JDBC_DRIVER=com.mysql.jdbc.Driver
USER=YourUser
PASS=YourPassword
DB_URL=jdbc:mysql://IP:PORT/DB

Afterwards i edited my openConnection() method to use the properties file for loading the credientials of the connection.

public Connection openConnection() {

        Properties properties = new Properties();
        Connection connection = null;

        String path = System.getProperty("user.dir");

        path += "/src/database.properties";

        try(FileInputStream fin = new FileInputStream(path);) {

            properties.load(fin);

            try {
                Class.forName(properties.getProperty("JDBC_DRIVER"));

//              opening connection
                connection = (Connection) DriverManager.getConnection(properties.getProperty("DB_URL"),properties.getProperty("USER"),properties.getProperty("PASS"));

            } catch (ClassNotFoundException e) {
                System.out.println("This is from openConnection method");
                e.printStackTrace();
            } catch (SQLException f) {
                System.out.println("This is from openConnection method");
                f.printStackTrace();
            }
        } catch (IOException io) {
            System.out.println("This is from openConnection method");
            io.printStackTrace();
        }

        return connection;
    }

Sending username and password, Java application -> MySQL

From what i can read on the web, it dosent matter much if you encrypt or hash the password before you send it towards the sequel service from your Java application. An example i found is that the sequel service dosent have a "receive hash method and authenticate". And even if it did the hash would need to be in the program somewhere. And when the program has access to it, others also have access to it if they really want it. Also if the hash is whats needed to authenticate than your back to where you can just as well use the clear text password.

The discussion than ends on "what is the best approach". Some suggest a keyserver / auth system in between the application and sequel service, using a datastore setup on the server side, using the OS "wallet" (example Windows registry) or creating a database user with minimum permissions to just get the job done / or a read only DB "read_only=1 in my.cnf".

I tried the 3'rd option and created a "DBaccess" user, with only the select permission to retrieve data, no administrative rights and random generated password by MySQL.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.