Java .class
files can be decompiled fairly easily. How can I protect my database if I have to use the login data in the code?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
Never hard-code passwords into your code. This was brought up recently in the Top 25 Most Dangerous Programming Mistakes:
You should store configuration information, including passwords, in a separate file that the application reads when it starts. That is the only real way to prevent the password from leaking as a result of decompilation (never compile it into the binary to begin with).
For more information about this common mistake, you can read the CWE-259 article. The article contains a more thorough definition, examples, and lots of other information about the problem.
In Java, one of the easiest ways to do this is to use the Preferences class. It is designed to store all sorts of program settings, some of which could include a username and password.
In the above code, you could call the
setCredentials
method after showing a dialog askign for the username and password. When you need to connect to the database, you can just use thegetUsername
andgetPassword
methods to retrieve the stored values. The login credentials will not be hard-coded into your binaries, so decompilation will not pose a security risk.Important Note: The preference files are just plain text XML files. Make sure you take appropriate steps to prevent unauthorized users from viewing the raw files (UNIX permissions, Windows permissions, et cetera). In Linux, at least, this isn't a problem, because calling
Preferences.userNodeForPackage
will create the XML file in the current user's home directory, which is non-readable by other users anyway. In Windows, the situation might be different.More Important Notes: There has been a lot of discussion in the comments of this answer and others about what the correct architecture is for this situation. The original question doesn't really mention the context in which the application is being used, so I will talk about the two situations I can think of. The first is the case in which the person using the program already knows (and is authorized to know) the database credentials. The second is the case in which you, the developer, are trying to keep the database credentials secret from the person using the program.
First Case: User is authorized to know the database login credentials
In this case, the solution I mentioned above will work. The Java
Preference
class will stored the username and password in plain text, but the preferences file will only be readable by the authorized user. The user can simply open the preferences XML file and read the login credentials, but that is not a security risk because the user knew the credentials to begin with.Second Case: Trying to hide login credentials from the user
This is the more complicated case: the user should not know the login credentials but still needs access to the database. In this case, the user running the application has direct access to the database, which means the program needs to know the login credentials ahead of time. The solution I mentioned above is not appropriate for this case. You can store the database login credentials in a preferences file, but he user will be able to read that file, since they will be the owner. In fact, there is really no good way to use this case in a secure way.
Correct Case: Using a multi-tier architecture
The correct way to do it is to have a middle layer, in between your database server and your client application, that authenticates individual users and allows a limited set of operations to be performed. Each user would have their own login credentials, but not for the database server. The credentials would allow access to the middle layer (the business logic tier) and would be different for each user.
Every user would have their own username and password, which could be stored locally in a preferences file without any security risk. This is called a three-tier architecture (the tiers being your database server, business logic server, and client application). It is more complex, but it really is the most secure way to do this sort of thing.
The basic order of operations is:
getInventoryList
.Note that in the entire process, the client application never connects directly to the database. The business logic tier receives a request from an authenticated user, processes the client's request for an inventory list, and only then executes a SQL query.
This question shows how to store passwords and other data in an encrypted file: Java 256-bit AES Password-Based Encryption
No matter what you do, the sensitive information will be stored in some file somewhere. Your goal is to make it as difficult to get as possible. How much of this you can achieve depends on your project, needs and thickness of your company's wallet.
The best way is not to store any passwords anywhere. This is achieved by using hash functions to generate and store password hashes:
Unrelated note: In the old days of the internet, when you click 'forgot my password' link, websites would email you your plain text password. They were probably storing those in a database somewhere. When hackers gained access to their database, they would gain access to all the passwords. Since many users would use the same password in multiple websites, this was a huge security problem. Luckily, nowadays this is not the common practice.
Now comes the question: what's the best way to store passwords? I would consider this (authentication and user management service stormpath's) solution a pretty damn ideal one:
Obviously you're not the google or a bank, so this is an overkill solution for you. But then comes the question: How much security your project requires, how much time and money you have?
For many applications, although not recommended, storing hard-coded password in the code might be a good enough solution. However, by easily adding couple of extra steps of security from the above list, you can make your application much more secure.
For example, let's assume step 1 is not be an acceptable solution for your project. You don't want users to enter password every time, or you don't even want/need users to know the password. Still you have sensitive information somewhere and you want to protect this. You have a simple application, there is no server to store your files or this is too much hassle for your project. Your application runs on environments where it is not possible to have files securely stored. This is one of the worst case, but still with some additional security measure you can have much safer solution. For example, you can store the sensitive information in a file, and you can encrypt the file. You can have the encryption private key hard coded in the code. You can obfuscate the code, so you make it a bit more difficult for someone to crack it. There are many libraries exists for this purpose, see this link. (I want to warn you one more time that this is not 100% secure. A smart hacker with right knowledge and tools can hack this. But based on your requirements and needs, this might be a good enough solution for you).
Put the password into a file that the application will read. NEVER embed passwords in a source file. Period.
Ruby has a little-known module called DBI::DBRC for such usage. I have no doubt that Java has an equivalent. Anyway, it is not difficult to write one.
Are you writing a web application? If so, use JNDI to configure it externally to the application. An overview is available here:
MD5 is a hash algorithm, not an encryption algorithm, in short u cant get back wat u hashed, u can only compare. It should ideally be used when storing the user authentication information and not db username and password. db username and pwd should be encrypted and kept in a config file, to do the least.