18

I need to store database passwords in a config file. For obvious reasons, I want to encrypt them (preferably with AES). Does anyone know a Delphi implementation that is easy to introduce into an existing project with > 10,000 lines of historically grown (URGH!) source code?

Clarification: Easy means adding the unit to the project, adding max. 5 lines of code where the config file is read and be done with it. Should not take more than 15 minutes.

Another clarification: The password is needed in order to create a connection to the db, not to support a user management scheme for the application. So using hashes does not help. The db engine checks if the password is valid, not the app.

Treb
  • 19,903
  • 7
  • 54
  • 87
  • Which database? There are better ways nowadays to connect than using plain, older user/password pairs –  Oct 13 '10 at 07:15
  • If you are using windows then you can check this article: [Secure way to store password in Windows][1] [1]: http://stackoverflow.com/questions/13145112/secure-way-to-store-password-in-windows – wittrup Sep 12 '13 at 00:33

15 Answers15

18

I second the recommendation for David Barton's DCPCrypt library. I've used it successfuly in several projects, and it won't take more than 15 minutes after you've read the usage examples. It uses MIT license, so you can use it freely in commercial projects and otherwise. DCPCrypt implements a number of algorithms, including Rijndael, which is AES.

There are many googlable stand-alone (single-unit) implementations too - the question is which one you trust, unless you are prepared to verify the correctedness of a particular library yourself.

Marek Jedliński
  • 7,088
  • 11
  • 47
  • 57
15

For typical authentication purposes, you don't need to store the passwords, you only need to check if the password entered by the user is correct. If that's your case then you can just store a hash signature (e.g. MD5) instead and compare it with the signature of the entered password. If the two signatures match the entered password is correct.

Storing encrypted passwords may be dangerous because if someone gets your "master" password they can retrieve passwords of all your users.

If you decide to use MD5 you can use MessageDigest_5.pas which comes with Delphi (at least it's included with my copy of Delphi 2007). There are also other implementations with Delphi source code you can choose from.

Ondrej Kelle
  • 36,941
  • 2
  • 65
  • 128
  • 4
    +1 for mentioning `hashing` and the dangers of storing passwords. Never ever store passwords (don't even think of encrypting them!). – Jeroen Wiert Pluimers Oct 13 '10 at 09:52
  • 2
    If he's discussing storing the password for the database connections, does the need to hash apply? You need the actual password to connect to the database. Or are you suggesting to distribute the master database password to all of your users for them to enter? – Eric G Aug 26 '14 at 16:59
8

I think Turbopower LockBox is an excellent library for criptography:

http://sourceforge.net/projects/tplockbox/

I don't know if it's too big for your uses but it is very easy to use and you can encrypt a string with 5 lines of code. It is all in the examples.

Giacomo Degli Esposti
  • 2,392
  • 1
  • 15
  • 20
  • It's old and not mantained. It does not support some needed improvements (i.e. block ciphers, larger keys). There are efforts to updated it, but right now it's not the library to use. –  Oct 13 '10 at 07:05
3

TOndrej has the right approach. You should never store a password using a reversible cypher. As it was correctly pointed out, if your "master" key were ever compromised, the entire system is compromised. Using a non-reversible hash, such as MD5, is much more secure and you can store the hashed value as clear text. Simply hash the entered password and then compare it with the stored hash.

Allen Bauer
  • 16,657
  • 2
  • 56
  • 74
  • 5
    Hashing is not an option, I need the password to establish a connection with the database. I have no control over the db whatsoever. – Treb Nov 05 '08 at 07:55
3

I've always user Turbopower Lockbox. It works well, and very easy to use. I actually use it for exactly the same thing, storing a password in a config text file.

http://sourceforge.net/projects/tplockbox/

Steve
  • 6,382
  • 3
  • 41
  • 66
3

TurboPower LockBox 3 (http://lockbox.seanbdurkin.id.au/) uses automatic salting. I recommend against Barton's DCPCrypt because the IV's are not salted. In some situations this is a very serious sercurity flaw.

Contrary to an earlier commment, LB3's implementation of AES is fully compliant with the standard.

Sean B. Durkin
  • 12,659
  • 1
  • 36
  • 65
  • 1) Is version 3 stable now? 2) License has been changed to GPL3 from Mozilla, and I wonder if you have the right to do it. Many commercial developers prefer to stay away from GPL libraries. –  Oct 13 '10 at 10:31
  • 1) For status see the website; 2) No that is not correct. No licensing on either of the two LockBox libraries has ever changed. LockBox 2 is released under MPL; LockBox 3 is released under LGPL3 (not GPL). LB2 and LB3 do not share any common source code. No commercial developer would ever eschew LGPL - that would be just irrational. – Sean B. Durkin Oct 22 '10 at 03:46
2

I've used this library, really quick to add. But wiki shows few more solutions.

cleg
  • 4,862
  • 5
  • 35
  • 52
2

Even if you encrypt, it seems to me that your decryption key as well as the encrypted password will both be in your executable, which means that in no way is just security by obscurity. Anyone can take the decryption key and the encrypted passwords and generate the raw passwords.

What you want is a one-way hash.

Bruce McGee
  • 15,076
  • 6
  • 55
  • 70
Nick
  • 13,238
  • 17
  • 64
  • 100
  • One way hash is ideal, but there is no way to decrypt it to use it again. It sounds like he needs to read the password out so his application can connect to the database. Hashes only work if you want to verify you got the same password you previously stored. – Jim McKeeth Sep 25 '08 at 16:09
  • Hashing is not an option, I need the password to establish a connection with the database. I have no control over the db whatsoever. – Treb Nov 05 '08 at 07:56
  • But Nick is right. If you store the key into your application, you just made it only a (very) little harder to decrypt the password. You need to protect the key as well. –  Oct 13 '10 at 07:14
1

Just a reminder.

If you don´t need to interoperate with others crypt libs, then DCP or LockBox would do the job.

BUT

if you need it to be fully compliant with the rinjdael specs, forget free components, they´re kinda "lousy" most of the time.

1

As others have pointed out, for authentication purposes you should avoid storing the passwords using reversible encryption, i.e. you should only store the password hash and check the hash of the user-supplied password against the hash you have stored. However, that approach has a drawback: it's vulnerable to rainbow table attacks, should an attacker get hold of your password store database.

What you should do is store the hashes of a pre-chosen (and secret) salt value + the password. I.e., concatenate the salt and the password, hash the result, and store this hash. When authenticating, do the same - concatenate your salt value and the user-supplied password, hash, then check for equality. This makes rainbow table attacks unfeasible.

Of course, if the user send passwords across the network (for example, if you're working on a web or client-server application), then you should not send the password in clear text across, so instead of storing hash(salt + password) you should store and check against hash(salt + hash(password)), and have your client pre-hash the user-supplied password and send that one across the network. This protects your user's password as well, should the user (as many do) re-use the same password for multiple purposes.

Mihai Limbășan
  • 64,368
  • 4
  • 48
  • 59
  • 1
    Hashing is not an option, I need the password to establish a connection with the database. I have no control over the db whatsoever. But thanks gor the detailed explanation! – Treb Nov 05 '08 at 07:57
1

I reccomend using some type of salt. Do not store crypt(password) in config file, but insted of this store crypt(salt + password). As 'salt' you can use something that is required to open database, eg. db_name+user_name. For crypt function you can use some well known algortithm as AES, Idea, DES, or something as simple as xoring each byte with byte from some other string, that string will be your key. To make it more different to solve you can use some random bytes, and store them.

So to store:

  1. init_str := 5 random bytes
  2. new_password := salt + password // salt := db_name + user_name
  3. crypted_password = xor_bytes(init_str + new_password, 'my keyphrase')
  4. crypted_password := init_str + crypted_password
  5. store crypted_password in config, as this will be bytes you can hexify or base64 it

And to connect:

  1. split data read from config into init_str and crypted_password
  2. new_password = xor_bytes(init_str + crypted_password, 'my keyphrase')
  3. password := remove (db_name + user_name) from new_password
Michał Niklas
  • 53,067
  • 18
  • 70
  • 114
0

Nick is of course right - I just assume you know what you are doing when you say you want to spend all of 15 minutes on implementing a security solution. The DCPCrypt library also implements a number of hashing algorithms if you decide to go that (better) route.

Marek Jedliński
  • 7,088
  • 11
  • 47
  • 57
0

A couple of solutions:

  • Don't store the password at all. If the database supports integrated authentication, use it. The process can be set to run with a specific identity, and be automatically authenticated by the database
  • Use Windows certificate stores and a certificate to encrypt your password. If you store the key used to crypt your password in your application, you have very little security anyway, you have to protect the key also.
0

You need to store it in a place where only the current user has acccess too.

Basically there are two ways to do this:

  1. Store it in an EFS encrypted file.
  2. Store it in the secure local storage.

Internet Explorer uses 2. But if you can get local access, you can decrypt both 1. and 2. if you have the right master key and algorithm (for instance, iepv can get at the Internet Explorer passwords).

So:
If you can, avoid storing passwords.
Look for alternatives (like Windows authentication, directory services, etc) first.

--jeroen

Community
  • 1
  • 1
Jeroen Wiert Pluimers
  • 23,965
  • 9
  • 74
  • 154
0

A simple but for most applications strong enough system is given by this Embarcadero's demo: https://edn.embarcadero.com/article/28325

UnDiUdin
  • 14,924
  • 39
  • 151
  • 249