16

I am creating an application and I need to connect to a database. The database requires login/password so the application can do operations like select and insert.

In the application I need to connect to the database using login and password, so the application is free to do some tasks on the database. My question is: how do I store and use a password to connect to the database without exposing the password?

I can't simply use a hash or encryption to store the password because the database must recognize the password (I think most or all databases must receive password as plain text).

.

.

Note: The connection is made by the application. No human input to do the connection.

(Edit)More info about the application: it is a web application using servlets/jsp. The database is on the same server of the application. The user for the application is a default user without complete admin powers, but it may insert/delete rows and do most things that involve queries and data modification in tables.

ceklock
  • 6,143
  • 10
  • 56
  • 78
  • Can you prompt an operator for a password at application start-up? – sarnold Jun 19 '12 at 01:03
  • The connection is made by the application. No human input. – ceklock Jun 19 '12 at 01:04
  • 3
    I think you need to describe a bit more about your application's environment. Is this a server app, client app, is the database on the same server, different server? Have you created a user with permissions only to insert? (You're not trying to log in as root are you?) Generally, you have to 'give some information away' and restrict login access to an ip range. –  Jun 19 '12 at 01:05

4 Answers4

10

The usual way this is done is to externalize the username/password to a property/config file which is read at runtime (whether or not you use native JDBC/JNDI/CDI/J2EE datasource/etc).

The file is protected via the O/S security by the sysadmins.

The O/S has better tools for protection than app code.

kentcdodds
  • 27,113
  • 32
  • 108
  • 187
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 1
    How to access this file? Is it encrypted? Have to decrypt the passwords? How do I pass the password to the database connection? – ceklock Jun 19 '12 at 01:06
  • not sure how that is secure in client apps (where password is on the wire)? Care to elborate.... – Mitch Wheat Jun 19 '12 at 01:07
  • 1
    If you want to prevent someone looking over your shoulder and seeing password when you're editing the configuration file, you can use the [`stringScrambler`](https://github.com/kentcdodds/Java-Helper/blob/master/src/com/kentcdodds/javahelper/helpers/OtherHelper.java#L66) in the Java Helper Library. It's really simple, but really effective to prevent people from shoulder surfing your password... – kentcdodds Jun 19 '12 at 01:08
  • 1
    @tecnotron The file is plain text. I've seen this done many times on big commercial websites and servers. The file is safe because the sysadmins don't let anyone near the file system, so it's safe (and a lot easier) to be in plain text. You can encrypt if you want, but anything can be cracked with enough time and CPU, so it isn't "safe" if people have access to the file. You need to prevent access to the file except by sysadmin and the running java process. – Bohemian Jun 19 '12 at 02:37
  • @Bohemian - How would you allow for concurrent access for multiple users to this properties file? – dwjohnston May 26 '15 at 02:58
  • Here is a relevant question for this answer: http://stackoverflow.com/questions/1132567/encrypt-password-in-configuration-files – dwjohnston May 26 '15 at 02:59
7

You can use jasypt for the encryption.And store the username and password to datasource.properties file.

public Connection getConnection() throws IOException{
    try{
        BasicTextEncryptor encryptor = new BasicTextEncryptor();
        encryptor.setPassword("jasypt");

        Properties props = new EncryptableProperties(encryptor);
        props.load( this.getClass().getResourceAsStream("datasource.properties") );

        String driver = props.getProperty("datasource.driver");
        String url = props.getProperty("datasource.url");        
        String userName = props.getProperty("datasource.userName");          
        String password = props.getProperty("datasource.password");

        Class.forName(driver);
        Connection conn = DriverManager.getConnection(url, userName, password);
        conn.setAutoCommit(false);

        return conn;
    } catch(ClassNotFoundException e) {
        e.printStackTrace();
        return null;

    } catch(SQLException e) {
        e.printStackTrace();
        return null;
    }
}
JR Galia
  • 17,229
  • 19
  • 92
  • 144
  • Nice to know jasypt library. Do you know if the encryption/decryption process is secure? I would first store in a file all encrypted passwords that I need, and then try to decrypt the passwords (decrypt is the problem, because I think I would need another password...). But it seems that you don't need to decrypt anything with this library. If it works it is very good. – ceklock Jun 19 '12 at 01:32
  • Jasypt provides unidirectional and bidirectional encryption techniques. I just used the library for the connection string. http://www.jasypt.org/features.html – JR Galia Jun 19 '12 at 01:37
7

You should use a config file for this. use spring with JDBC to make your life easier!

http://www.youtube.com/watch?v=f-k823MZ02Q

Checkout the above awesome tutorial on the Spring framework and using JDBC. Watch all of his JDBC and spring tutorials. BTW, he covers how to store passwords in config files and wire beans etc.. Hope this helps.

Horse Voice
  • 8,138
  • 15
  • 69
  • 120
5

If it's a web app, deploy it on a Java EE app server and connect using a JNDI resource. Only the admin who set up the JNDI data resource needs to know about the credentials needed to connect. Users and developers don't even have to know them; just the JNDI lookup name.

It's not possible to completely eliminate the need for someone besides the database owner to know the username and password, but it is possible to restrict that knowledge to the app server owner.

You are also well advised to create separate credentials just for that application and GRANT it the minimum access and permissions needed to accomplish its tasks. There should be no knowledge of system tables or any other resources outside the province of the application. IF DELETE permission isn't necessary, don't grant it. If access should only be read only, that's what you should GRANT to that credential.

duffymo
  • 305,152
  • 44
  • 369
  • 561