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.
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.
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.
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;
}
}
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.