Link to home
Start Free TrialLog in
Avatar of sunshine737
sunshine737

asked on

how to hide database password written in the program

Hi,

Im looking for a mechanism that enables me to hide the password that we write in the program to connect to the database. For eg:-
conn = DriverManager.getConnection ("jdbc:oracle:thin:@fe64700:1521:-------","------------", "-------------");

above we give SID, userid and password, I somehow want to secure them, that is I dont want others who come accross my code to see these passwords. I dont know much about security, but I am looking for simpler solutions that doesnt make my prg complicated.
So any ideas, examples, code-snippets and contribution will be greatly appreciatted.

Thanks
Avatar of Mick Barry
Mick Barry
Flag of Australia image

don't hard code it, and instead have the user enter it.
However its stored in your code someone is going to be able to access it.
Have it inside configuration files.
if u r running over application server why not use Datasource?
 the App server encrypts the database password
Avatar of grim_toaster
grim_toaster

--> Have it inside configuration files.
But they're even easier to read!

What kind of application is it?  If running on an application server, it would be better to set up a datasource in the app server.  Advantages include connection pooling, and most will also encrypt the password for you.

If not, then you could do the encryption/decryption of the password yourself, many algorithms already available for Java.  What you've got to remember though is that you won't be able to stop a determined individual from acquiring the values, you've just got to make it as hard as possible - in a similar way to licence keys for some java applications.  The entire application is written in Java, therefore theoretically (and I do not condone this sort of behaviour), it would be possible to decompile the entire application to see how things are done.  You can make it harder by obfuscating the code, and other such things, but again, the determined individual will just crack it eventually.
> --> Have it inside configuration files.
> But they're even easier to read!

If you give the code to someone to read it you do not have to also distribute the config files. On the other hand if someone buys the application I do not see why there shouldn't be info about the database.
Hi vihar123,

I don't think that can be done, you can only use variables or read it from a file.

Maybe you could encrypt it in some way?

nesnemis
Avatar of sunshine737

ASKER

wow thanks for all the contributions,

how to make configuration files, can i get an other example other than the javalamanac link, and how to encrypt and decrypt......

from all above i can see that i can only make it hard but not completely secure it, so i think i should either go for configuration or encrypt, depending on which, is more easier...

can i please get some examples :-)
Dear vihar123,

I do not know whether you can apply it or not, but try to locate your connection to database as one .java file. Create .class from that .java file and never ever give that .java to your user. So, although in the development phase, simply use the .class file and never include .java file to access the database. That should make your database password inaccessible.

I hope that helps.

Dave
>> Create .class from that .java file and never ever give that .java to your user.
Java decompilers exist to make a java file from a class file.
It won't be difficult to regenerate the SID/userID/password strings from that class file.
is it possible to get some examples of making configuration files and also encryption and decryption.......

thanks a lot
Even if you use a encrypted config file, the password can still be gotten by decompiling the source.
For example you'd just need to add a println() statement to print out the password before it is used.
>>>Even if you use a encrypted config file, the password can still be gotten by decompiling the source.
For example you'd just need to add a println() statement to print out the password before it is used.

so is there no way that i can secure it a little bit........????

I would like to try calling it from an other class file, how can i do this, can I get some examples
User's can still see it even if you call it from another class. The best suggestion is petmagdy's about the datasource.
>>>The best suggestion is petmagdy's about the datasource

where can i get more information about it, i mean how to go about with this datasource.
What server are you using? They should have information about how to define and use datasources.
well then just for learning sake.........
i have encrypted using a prog that i have written seperately, now how can I use this encryption in my application....

for eg:- i have this prg

import javax.crypto.*;

public class SecureDB {
        Cipher ecipher;
        Cipher dcipher;
   
        SecureDB(SecretKey key) {
            try {
                ecipher = Cipher.getInstance("DES");
                dcipher = Cipher.getInstance("DES");
                ecipher.init(Cipher.ENCRYPT_MODE, key);
                dcipher.init(Cipher.DECRYPT_MODE, key);
   
            } catch (javax.crypto.NoSuchPaddingException e) {
            } catch (java.security.NoSuchAlgorithmException e) {
            } catch (java.security.InvalidKeyException e) {
            }
        }
   
        public String encrypt(String str) {
            try {
                // Encoding the string into bytes using utf-8
                byte[] utf8 = str.getBytes("UTF8");
   
                // Encrypt
                byte[] enc = ecipher.doFinal(utf8);
   
                // Encoding bytes to base64 to get a string
                return new sun.misc.BASE64Encoder().encode(enc);
            } catch (javax.crypto.BadPaddingException e) {
            } catch (IllegalBlockSizeException e) {
            }
             catch (java.io.IOException e) {
            }
            return null;
        }
   
        public String decrypt(String str) {
            try {
                // Decode base64 to get bytes
                byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
   
                // Decrypt
                byte[] utf8 = dcipher.doFinal(dec);
   
                // Decode using utf-8
                return new String(utf8, "UTF8");
            } catch (javax.crypto.BadPaddingException e) {
            } catch (IllegalBlockSizeException e) {
            }
            catch (java.io.IOException e) {
            }
            return null;
        }
       
public static void main(String args[])
{
 
    try {
        // Generating a temporary key
        SecretKey key = KeyGenerator.getInstance("DES").generateKey();
   
        // Creating encrypter/decrypter class
        SecureDB encrypter = new SecureDB(key);
   
        // Encrypt
        String encrypted1 = encrypter.encrypt("abcd");
        String encrypted2 = encrypter.encrypt("test");
        String encrypted3 = encrypter.encrypt("2004");
        System.out.println(encrypted1);
        System.out.println(encrypted2);
        System.out.println(encrypted3);
   
        // Decrypt
        String decrypted1 = encrypter.decrypt(encrypted1);
        String decrypted2 = encrypter.decrypt(encrypted2);
        String decrypted3 = encrypter.decrypt(encrypted3);
        System.out.println(decrypted1);
        System.out.println(decrypted2);
        System.out.println(decrypted3);
    } catch (Exception e) {
    }

}
}


-------------

now how can i use or call the above prg in my application where im giving these passwords
Create an instance of the SecureDB and then call the methods on it.
>>>Create an instance of the SecureDB and then call the methods on it.

can you give me an example, its little confusing
You already have examples inside the main method.

> SecretKey key = KeyGenerator.getInstance("DES").generateKey();

You create a SecretKey object.

>  SecureDB encrypter = new SecureDB(key);

You create a enw instance of the SecureDB class.

> String encrypted2 = encrypter.encrypt("test");

You encrypt the "test" key.

> String decrypted3 = encrypter.decrypt(encrypted3);

You decrypt the key and you get the result back (it should be "test").
what i would like to do here is call these encrypted values in my other application.......so the real values stay in securedb prg and in my other application i use these encrypted values, how can i do this?
Just create a reference to the SecureDB class, exactly like it is done inside the main method.
when im doing like this its giving me this error

java.sql.SQLException: E/A-Exception: Connection refused(DESCRIPTION=(TMP=)(VSNNUM=153092352)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))
 
-----------------------
try
        {
            DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
            try
            {
            SecretKey key = KeyGenerator.getInstance("DES").generateKey();
            DesEncrypter encrypter = new DesEncrypter(key);
           
            }
            catch (Exception NoSuchAlgorithmException)
            {}
           
            conn1 =
            DriverManager.getConnection ("jdbc:oracle:thin:@fe64700:1521:encrypted1","encrypted1", "encrypted1");
Are you sure the username/password are "encrypted1" and "encrypted1"? Check the database and what suername/password it expects and try again. Als omake sure that you are trying to connect to the correct database (check database name).
>>>Are you sure the username/password are "encrypted1" and "encrypted1"? Check the database and what suername/password it expects and try again. Als omake sure that you are trying to connect to the correct database (check database name).

well actually what im trying to do is encrypt sid, uid and pw using this below prg and create a refrence in the other prg like i did above, but its giving me this error
-----java.sql.SQLException: E/A-Exception: Connection refused(DESCRIPTION=(TMP=)(VSNNUM=153092352)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))
 
-------------------------------------------------------------------------


import javax.crypto.*;

public class DesEncrypter {
        Cipher ecipher;
        Cipher dcipher;
   
        DesEncrypter(SecretKey key) {
            try {
                ecipher = Cipher.getInstance("DES");
                dcipher = Cipher.getInstance("DES");
                ecipher.init(Cipher.ENCRYPT_MODE, key);
                dcipher.init(Cipher.DECRYPT_MODE, key);
   
            } catch (javax.crypto.NoSuchPaddingException e) {
            } catch (java.security.NoSuchAlgorithmException e) {
            } catch (java.security.InvalidKeyException e) {
            }
        }
   
        public String encrypt(String str) {
            try {
                // Encoding the string into bytes using utf-8
                byte[] utf8 = str.getBytes("UTF8");
   
                // Encrypt
                byte[] enc = ecipher.doFinal(utf8);
   
                // Encoding bytes to base64 to get a string
                return new sun.misc.BASE64Encoder().encode(enc);
            } catch (javax.crypto.BadPaddingException e) {
            } catch (IllegalBlockSizeException e) {
            }
             catch (java.io.IOException e) {
            }
            return null;
        }
   
        public String decrypt(String str) {
            try {
                // Decode base64 to get bytes
                byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
   
                // Decrypt
                byte[] utf8 = dcipher.doFinal(dec);
   
                // Decode using utf-8
                return new String(utf8, "UTF8");
            } catch (javax.crypto.BadPaddingException e) {
            } catch (IllegalBlockSizeException e) {
            }
            catch (java.io.IOException e) {
            }
            return null;
        }
       
public static void main(String args[])
{
 
    try {
        // Generating a temporary key
       
        SecretKey key = KeyGenerator.getInstance("DES").generateKey();
   
        // Creating encrypter/decrypter class
        final DesEncrypter encrypter = new DesEncrypter(key);
   
        // Encrypt
        String encrypted1 = encrypter.encrypt("test_sid");
        String encrypted2 = encrypter.encrypt("test_uid");
        String encrypted3 = encrypter.encrypt("test_pw");
        System.out.println(encrypted1);
        System.out.println(encrypted2);
        System.out.println(encrypted3);
   
        // Decrypt
        String decrypted1 = encrypter.decrypt(encrypted1);
        String decrypted2 = encrypter.decrypt(encrypted2);
        String decrypted3 = encrypter.decrypt(encrypted3);
        System.out.println(decrypted1);
        System.out.println(decrypted2);
        System.out.println(decrypted3);
    } catch (Exception e) {
    }

}
}
Are you sure the database name you are trying to connect to is correct?
>>>Are you sure the database name you are trying to connect to is correct?

ya im quite sure,

is my above code right or there are any mistakes???? I mean is the purpose rightly coded
>  I mean is the purpose rightly coded

People can still see the username and password if they decompile the class. Note these lines:

String encrypted2 = encrypter.encrypt("test_uid");
String encrypted3 = encrypter.encrypt("test_pw");

where you explicitly say what the username/password is.
>>>People can still see the username and password if they decompile the class. Note these lines:

i will not give them this DesEncrypter prg where im encrypting them, and in the main prog, fo eg im calling them in the prg GUI5, so here even when they read they will not know it.......

well its not secured enough but just for learning sake i want to know how can i use this DesEncrypter prg in my GUI5 prg and encrypt the real values.
------------------
public class gui4 extends javax.swing.JFrame  {

 Connection conn1;      
       Statement stmt1;      
       ResultSet rset1 = null;      
       
        try
        {
            DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
            try
            {
            SecretKey key = KeyGenerator.getInstance("DES").generateKey();
            DesEncrypter encrypter = new DesEncrypter(key);
           
            }
            catch (Exception NoSuchAlgorithmException)
            {}
           
            conn1 =
            DriverManager.getConnection ("jdbc:oracle:thin:@fe64700:1521:encrypted1","encrypted2", "encrypted3");
           
> i will not give them this DesEncrypter prg where im encrypting them, and in the main prog, fo eg im calling them in the prg
> GUI5, so here even when they read they will not know it.......

The problem is not the DesEncrypter/Decrypter but the place where you will pass the username/password from/to. I still believe the best solution is the datasource.
>>>>The problem is not the DesEncrypter/Decrypter but the place where you will pass the username/password from/to. I still believe the best solution is the datasource.


ok experience does matter, ill take your advise and close this question but i want to learn, so please help me....two things
1. how can I call these values in my main program, what i want is that i encrypt using this prg and give the encrypted values in the other prog where im connecting to db
2. some information about datasource, steps on how to go about it
1. You already have examples on how you can encrypt and decrypt the variables. The code in the main method of the examples you psoted does exactly this, it shows how you can use your class to encrypt/decrypt values. Maybe you mean somethign else that I cannot understand?

2. Defining the datasource depends on the application server you are using. Better have a look at the app server's documents. For tomcat for example you can have a look here: http://jakarta.apache.org/tomcat/tomcat-4.1-doc/jndi-datasource-examples-howto.html
>>>Maybe you mean somethign else that I cannot understand?

ok let me explain:-

Im having prog A that encrypts and decrypts

Im having prog B that has to call these encrypted values

that is i want to encrypt the values sid, uid and pw in prog A and it gives the result something like this
jgZM+/INgE8ep+Y0l9Tj8Q==
aEbCkATVNnYep+Y0l9Tj8Q==
LeH+N3h1T+0=

so these above values i want to use them in my B prog to connect to the database, so when others read they cannot understand and the prog A i dont want to show anyone.

Well i know its not that secured but just i want to learn :-)

hope its clear, when not ill be glad to explain more clearly......thanks

> so these above values i want to use them in my B prog to connect to the database, so when others read they cannot
 > understand and the prog A i dont want to show anyone.

You mean you do not want them to have access to the source code of the programme B? Then you will need to put it up on a web server or something like this and call it up by using HTTP (or any other protocol, depends on how it is running).
>>>>You mean you do not want them to have access to the source code of the programme B? Then you will need to put it up on a web server or something like this and call it up by using HTTP (or any other protocol, depends on how it is running).

ya exactly something like this. but i dont know much abt HTTP..etc

but i think u got my point, i want to use the encrypted values in my B prg in the place or original values
You will need to put it up as a servlet or a web service. For more info on these concepts have a look here: http://java.sun.com/j2ee/1.4/docs/tutorial/doc/
thanks and how do i use the encrypted values in prog B cause when im doing like below its give me this error

-----java.sql.SQLException: E/A-Exception: Connection refused(DESCRIPTION=(TMP=)(VSNNUM=153092352)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))

 
try
        {
            DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
            try
            {
            SecretKey key = KeyGenerator.getInstance("DES").generateKey();
            DesEncrypter encrypter = new DesEncrypter(key);
           
            }
            catch (Exception NoSuchAlgorithmException)
            {}
           
            conn1 =
            DriverManager.getConnection ("jdbc:oracle:thin:@fe64700:1521:encrypted1","encrypted2", "encrypted3");

-------------------

class encrypt
{
public static void main(String args[])
{
 
    try {
        // Generating a temporary key
       
        SecretKey key = KeyGenerator.getInstance("DES").generateKey();
   
        // Creating encrypter/decrypter class
        final DesEncrypter encrypter = new DesEncrypter(key);
   
        // Encrypt
        String encrypted1 = encrypter.encrypt("test_sid");
        String encrypted2 = encrypter.encrypt("test_uid");
        String encrypted3 = encrypter.encrypt("test_pw");
        System.out.println(encrypted1);
        System.out.println(encrypted2);
        System.out.println(encrypted3);
   
        // Decrypt
        String decrypted1 = encrypter.decrypt(encrypted1);
        String decrypted2 = encrypter.decrypt(encrypted2);
        String decrypted3 = encrypter.decrypt(encrypted3);
        System.out.println(decrypted1);
        System.out.println(decrypted2);
        System.out.println(decrypted3);
    } catch (Exception e) {
    }

}
}

ASKER CERTIFIED SOLUTION
Avatar of girionis
girionis
Flag of Greece image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial