Hi all.
I was just wondering, when making a program with things like database usernames and passwords in, what is the best way to store the data securely?
Lewis
Use MD5 to store the password. That way the password isn't really there, just the hash.
What database are you planning on using? Some, like SQLite, have built-in encryption. However, many dba's only hash the password and leave the names unencrypted. However, hashing the password will not allow you to email the password if they forget since it's a one way encryption (message digest) but you can simply hash the password they are using to log in with and then compare them.
EDITED: Paul was posting when I wrote this.
Hi all,
I dont think i explained myself enough. What i meant was how do i keep the username and password to connect to a database server secure in my program, nothing to do with the database.
Lewis
The only thing that comes to mind would be to store pieces of the usename and password in a bunch of variables and then add the variables together in various lines of code right before you need to use them.
To make it more convoluted you could store the asc codes in multiple constants (along with come garbage constants then build the password and name in pieces .
I bet guys that deal with encryption are having a heart attack about now. ;)
It wouldn't stop a hacker though.
Yes thats one way I suppose.
I was just thinking about it the other night and I realised, well although it would be public for anyone to access and use the program, I wouldnt want people connecting direct to my database if that makes sense?
I had thought of encryption, but then there is m next question... Where do you store the cipher key safely?
Lewis
Do what Paul said and hash the password using MD5. Then store that hash as a standard string.
When the user enters a password, hash that password and compare the two hashes. If they match then the same string was used to create the matching hash, so the entered password matches the stored one (in hash format) in the exe.
This is one way of ensuring security without putting a keygen inside your app (which can be disasembled). I have a small utility that does the same. I thought i probably wouldn't sell more than a 1000 copies, so i put an array inside the app containing 1000 MD5 serial number hashes. This allows 1000 people to all have unique passwords, and whats more, they can never be forcibly removed from the exe, well not without a Cray and about a thousand years spare. ;)
A good link to find out other useful tips:
http://inner-smile.com/nocrack.phtml (http://inner-smile.com/nocrack.phtml)
Hi Garry.
I think you have also misunderstood my intentions. So I will describe what I intend to do in a nut shell...
I wirte a program called phonebook.exe, this program connects to an international telephone database on the internet with a specified username and password which is only known to the programmer, not the end user.
But if i do this in my code...
string username = "username321";
string password = "password123";
connect('servername',username,password);
.....
Obviously a hacker could take apart my program and see the username and password. I use hashing all the time for security but this is not one of those cases where I can use it and the user has no control over the username and password.
Does this make more sense?
Lewis
Ah right. String literals are a problem because a simple hex viewer can see them. Try not to use Username and password as variables for a start. Use reserved WinAPI words such as:
FindWindowEx = "username";
GetModuleHandle = "password";
This should be ok if you dont import these functions from outside. Also build the literal strings dynamically using character ascii values etc.
QuoteAlso build the literal strings dynamically using character ascii values etc.
which is what I suggested above ;)
Garry. Im no expert on nternals of compiled programs but am I right in thinking that variable names only exist in the source code for programming sake? When they are compiled they use different internal names dont they?
Larry, I think that will be the way to go for constructing the strings to keep them safe.
Lewis
Pre-encrypt the data using hash, md5, shifting, or what ever.
Store this in the program and have a decrypt routine in you code to recover it.
At least this way it will not be readable by a hacker.
Well in that case. You first line of defense is encrypting the entire executable, either by compression or a protection program. At least that way any schmoke with a hex editor won't be able to see your plaintext.
EXECryptor http://www.strongbit.com/execryptor.asp is a good one to try. It supported IBasic executables so should work with Aurora as well. PECompact http://www.bitsum.com/ will also work and it is free for personal use, it is just a compressor though.
Next don't store the password and username as plain text. Use a 1 to 1 hash, even a simple XOR will help. That way it can be converted back to plaintext using a function before the connect call. If you don't know what I mean then let me know and I'll write a simple 1 to 1 hash for you to use.
Paul.
Quote from: Paul Turley on January 12, 2007, 06:32:40 AM
That way it can be converted back to plaintext using a function before the connect call.
And call that function 'FindWindowEx' or someother WinAPI name. That's what i meant Zen. ;)
I sort of understand the idea behind what you say. Do you mean like swapping characters for different ones?
Lewis
Yes. A substitution cypto. Any hacker worth his salt can break simple substituion cryptos, which is why you need to encrypt the executable as well.
For example, here is a very insecure one, based on the principle that any value when xor'd twice by the same constant will result in the original value. You store the giberish string and then call the encrypt function before you connect to the server. The only benefit is the result is not readable ;)
sub main()
{
string str = encrypt("Hello World");
print( str );
print( encrypt(str) );
while GetKey() = "";
}
sub encrypt(string in),string
{
for( int x = 0; x < len(in); x++)
{
in[x] = in[x] XOR 128;
}
return in;
}
Yeah that makes perfect sense to me Paul. Its start I guess. Just why is it XOR 128?
Lewis
127 is the end of the printable range of characters. Otherwise you end up with NULL's in your string. You can use any from 128 to 255 for XOR'ing ASCII values.
Ohh right yeah I get it now. Thanks a lot Paul.
Lewis
Randall
Zen wrote
QuoteI think you have also misunderstood my intentions. So I will describe what I intend to do in a nut shell...
I wirte a program called phonebook.exe, this program connects to an international telephone database on the internet with a specified username and password which is only known to the programmer, not the end user.
That means the login and password is being sent in plain text :) Unless you have an SSL connection to the database server .... but still, it is always insecure to allow many or any users direct access to your database. Best bet is to run a server program between the database and the client application to filter out any criminals and other such bad behavior.
At the moment i do not actuall have a specific database but it is most likely to be mysql whice does support connections over ssl. I have just been thinking ahead on this.
Lewis