13

I'm developing a desktop application and it required connecting to a remote MySQL database server, currently I save all information (server IP, TCP port, username, password, database name) needed for the connection in a configuration file call app_config.property.
I realize this is not secure way of doing things and I would like to know the most secure and professional way of keeping secure data like this.

I developed it in Java 7.0; my intention is to run it on Windows 7 as well as Ubuntu Linux.

dimi
  • 175
  • 1
  • 1
  • 7
  • 1
    Where will you store the encryption key to decrypt the information? – Fiasco Labs Oct 14 '15 at 04:51
  • Which OS are you using? IIRC in .NET there are some options for this. – S.L. Barth Oct 14 '15 at 05:34
  • @S.L.Barth I developed it in java 7.0 my intention is to run it in Windows 7 as well as Linux Ubuntu – dimi Oct 14 '15 at 05:53
  • @Begueradj I developed it in java 7.0 my intention is to run it in Windows 7 as well as Linux Ubuntu – dimi Oct 14 '15 at 05:55
  • Ok, I've taken the liberty of editing that into your question. BTW if you disagree with edits, you can roll them back. To roll an edit back, click on the "edited ... ago" link. That takes you to the revision history, where you can roll back to a previous version of your post. Meanwhile, good luck, hope you'll get a useful answer! – S.L. Barth Oct 14 '15 at 05:57
  • 1
    @S.L.Barth Your editing is helpful to improving the question,i appreciate you help – dimi Oct 14 '15 at 06:00
  • Use the operating system's password manager rather than store the password yourself. Otherwise there's no proper way, you'll have to keep it clear-text (or some obfuscated, perfectly recoverable equivalent that only provides illusion of security). – Steve Dodier-Lazaro Oct 14 '15 at 10:31
  • You could use ESAPI to encrypt your configuration files. There are some details here: https://www.owasp.org/index.php/How_to_encrypt_a_properties_file – whoami Oct 16 '15 at 08:38

6 Answers6

4

Data stored in a text file stay there in clear format unless you encrypt that file itself.

As the other answerer said, better to store your credentials in the MySQL database itself. Hash and salt your password (and why not using a pepper too?)

Useful links with very good answers:

  1. How to securely hash passwords?
  2. How to store salt?
  3. What is the purpose of a Pepper?

EDIT:

Following your comments:

  • You either want to do the same thing as Wordpress, Joomla and other famous CMS do: create a separate table where you can store such information.
  • Or may be you are hosting your web application on a server on which you are limited in order the number of DBs and tables within a DB you are allowed to create: in that case, you can create a PHP configuration file (instead of a text file) where you store that information and follow the good practices in such situations (such as protecting the folder in which this file is located with an .htaccess file)
  • 1
    problem is I have to save database credentials outside the database so saving a credentials in a file is the only solution I came up with – dimi Oct 14 '15 at 06:48
  • When my application starts it read my credential file and establish a connection with database server, all the users credentials are in database table,to establish a connection with database, my application must have a database credentials out side the database – dimi Oct 14 '15 at 07:00
  • @dilee You can create a separate table in your DB called for example where you store the credentials and other info (Wordpress does the same, then it reads that table via `wp-config.php` file) –  Oct 14 '15 at 07:05
3

If possible don't store the username and password in the configuration file, ask the user to provide a username and password when they open the application and create a login for the user on the database and only give that user the minimum set of permissions to the db tables that they need for the application to run.

https://www.digitalocean.com/community/tutorials/how-to-create-a-new-user-and-grant-permissions-in-mysql

user89186
  • 31
  • 1
  • I'm already managing user permissions in database but still i have to save database credentials some ware outside the database – dimi Oct 14 '15 at 06:22
1

There is not a secure way to do that. You can obfuscate, hide or do whatever you want, but if the user/password is in a configuration file or inside the code it will never be secure. Someone can always access the data/executable and get the user/password, the only difference is the difficulty to get that information (just reading a file or having to reverse engeneer the code). The only secure way is having the user introducing that data.

YoMismo
  • 195
  • 1
  • 6
1

Take the average PHP web application, like Wordpress, and it saves Mysql login in clear text. Of course the average user cannot see this, only users who have access to the code.

What I'm trying to say is that if this could be done otherwise, it probably would be done so.

You could setup a webservice that interacts with the database, and limit access and rights to the database more precisely, but I'm not sure if that really improves security, and I don't have time to think that out.

You could limit database rights per table to whatever is needed: select, update, delete, and/or insert.

SPRBRN
  • 7,449
  • 6
  • 35
  • 37
1

obfuscating the code will do this fine, I wouldn't use a config file in pure text.

but if you want a config file, you can have encrypted files in java, I myself have written a few encryption applications using AES and PPK (RSA). encrypt the file you can either encrypt the file with a key only your application code will know or you can use hardware IDs and salts so you cant move the config file across different computers.

using a byte stream you can encrypt and decrypt on the fly without changing files unless you want to.

This would be my suggestion for this specific scenario.

TheHidden
  • 4,315
  • 3
  • 22
  • 40
0

How do I secure sensitive information like system credentials in a configuration file?

It’s entirely true that if somebody has local access or root access to the system, they can certainly find the master key (also called the Key Encrypting Key or KEK). However, I find it is more likely that a remote attacker tries to obtain the key. There are methods that are resistant to most common remote attacks, and I recommend they are used in cases where you have sensitive information like database credentials.

The way I typically suggest this be handled is as follows:

At installation time, a random master key is generated. It is not hard-coded in the source code. It is stored on the local system either:

  1. in a randomly named file inside a randomly named folder, or else
  2. it is stored inside the metadata of a set of randomly named files inside a randomly named folder (using a portion of the mtime timestamp).

This master key is recovered when the system starts up, and is used to decrypt the data encrypting key (DEK). The master key is then cleared from memory. Its only purpose is to de/encrypt the DEK, which is stored in encrypted form in a config file. This DEK is used to encrypt any other secrets (like DB creds). Like the master key, the DEK is generated at installation time, encrypted with the KEK, and stored in a config file.

Advantages

  1. There is no hard-coded master key. Each installed agent has a different master key, so if a rogue customer purchases the product, learning the master key does no good for attacking a different customer or a different installed agent.
  2. If a remote attacker finds a means of exfiltrating file data, they will have difficulty given that the file name is random – typically an attacker will need to know the file name to exploit a path traversal issue, for example.
  3. If you store the master key in file metadata, then even if the file contents are exfiltrated, it’s useless. An attacker would require remote code execution to extract the key from file metadata. The files can be empty or (if you’re feeling like messing with attackers) can have random data – the file contents are not used, only the metadata.

How does the agent itself locate the master key, given the file name and folder name are random?
Good question!

We assume there is one folder known to the agent. Let’s say that this folder is named config/.
Within config/, the code searches for a folder matching *.kek. Within that folder, search for all files matching *.kpt. Sort the filenames in alphabetical order. Retrieve the metadata from each file, and assemble the bytes into the master key. If your master key is 256 bits, then the random file names should also have 256 bits of entropy so that a brute force search for file names is at least as difficult as a brute force search of the keyspace.

config/
    …
    BcFkVQ_ne5JGYj4K4W4pzMTnOYB2sYmBUQ78nu5Elo0.kek/
       z2eYwmfXnJBcnC9M8fDovXV8bIG_jgDtK5656eUOplw.kpt
       UUFcJYUeokiM-AzPawHGMjlMTOZAI17yBZQd48zT3_M.kpt
       WD2CbKJce6iXfZuyq8Zqe3u1xQN2Op_QR1u4PCm72AA.kpt

I have a code library that does this for you. It’s in Java and is implemented using the Java KeyStore interface. You can also implement the same thing as a C library, if that’s more suitable. We contributed the library to OWASP as open source: https://github.com/OWASP/SideKEK

A presentation talking about the system is available: https://raw.githubusercontent.com/OWASP/SideKEK/master/media/KeysUnderDoormats-slides-GlobalAppSecDC-2019-09-13.pdf

A common question is, “How is this not security by obscurity?” Security by obscurity is an attempt to keep a secret by making the method difficult to understand. Here the method is documented and can be shouted from the rooftops. The thing that is secret is the actual folder and filenames, just like a secret key in a well-documented encryption scheme like AES. A good guiding rule to follow is Kerckhoffs's principle: "A cryptosystem should be secure even if everything about the system, except the key, is public knowledge."

Frugal Guy
  • 41
  • 4
  • A few points to add: 1. Use a **secure** random number generator (secure PRNG) to generate keys. 2. I recommend you salt the DEK with a static Alias string when encrypting a secret. This way every secret is encrypted with a different key. The Alias need not be secret, only unique. This helps to make your code more understandable as well. – Frugal Guy Oct 13 '22 at 22:53