Hi,
I have a dilemma and would like to know other user’s views on the best way to proceed.
When someone purchases my software via PayPal, what is the best next step:
A) Inform them that they will receive download instructions within the next 24 hours (in order for me to hardcode a unique hashed database file and software password for their particular copy.
OR
B) Allow them to download instantly BUT then every user who buys my software will have exactly the same database hash, and the same default software password.
The default software password can be changed within the software itself, and is only to prevent unauthorised people accessing the software on the managers computer (as opposed to an anti-piracy feature) - so that is not the main issue.
The main issue is that each purchaser would have the same hash for the database, meaning that the databases would not be unique to each customer, and therefore compromise on security.
Example:
If customer “A” somehow obtained the database file of customer “B”, he would be able to view it in his copy and see all of customer "B"s data.
Any view or ideas welcome.
Thank you.
If a license key is issued to each customer and it does not change over time, why not base the salt/hash on some variant of their license key? If the license key does change over time, perhaps each customer could be issued one timeless license key for the database salt/hash and one that expires for conventional enabling/disabling of features/functionality.
I have no license key at all for my software.
I think you’re the only one who can answer that. 
Option A is a pain in the neck for you, and if you go on vacation for a few days you either need to have a computer with you or tell your customer to wait.
Option B may be less secure, but perhaps that’s not the end of the world depending on what the application is. If you were to require the user to set a password on first launch, rather than having a default password, wouldn’t the database be more secure if you used that password for it rather than a default password? (I’m obviously no expert on database security)
Would it not be possible to ask the user for a password, and create the database with it the first time the software is run ?
Then all you have to do is deliver the software.
I mostly hate buying something and needed to wait for a long time (read: +10 minutes) for activation instructions. IMO thats not a good way to deal with customers.
I use a Paypal php script to handle serial creating and invoice. This way the customers gets all he needed within minutes.
Michel,
Thank you for the excellent suggestion, but I have run into a small problem.
In my app’s open event, I can check for the existence of AC.db, and if it already exists, Return True.
If it does not already exist, then display a window asking the user to enter a 9 digit string (into a textfield) - then use that string to encode the database.
All is ok so far - but I have no idea how to then modify my current database code to decrypt the encryption key, the next time the app is run (as in line 3 of my code below)?
How would I replace 123456789, with whatever the user entered?
[code]Dim db As New SQLiteDatabase
db.DatabaseFile = SpecialFolder.ApplicationData.Child(“AC.db”)
db.EncryptionKey = EncodeHex(MD5(“123456789”))
If db.CreateDatabaseFile Then
db.SQLExecute(“CREATE TABLE Accounts(ACRef INTEGER PRIMARY KEY, Date TEXT, Description TEXT, Income TEXT, Expenses TEXT, IsIncome TEXT)”)
db.Close
Else
MsgBox(“Database not created”)
End If[/code]
Thank you.
[quote=81198:@Richard Summers]How would I replace 123456789, with whatever the user entered?
Dim db As New SQLiteDatabase
db.DatabaseFile = SpecialFolder.ApplicationData.Child(“AC.db”)
db.EncryptionKey = EncodeHex(MD5(“123456789”))
[/quote]
I would
- create a string module variable called, say, theKey
- upon launch of the app, request the password from your user, for instance through a modal window and an enterKey field with buttons OK and Cancel.
- If Cancel, quit the app.
- If OK, copy enterKey.Text to thekey
Then you code will read
[code]Dim db As New SQLiteDatabase
db.DatabaseFile = SpecialFolder.ApplicationData.Child(“AC.db”)
db.EncryptionKey = EncodeHex(MD5(theKey))[/code]
Having the user enter his password is the most secure way.
If you do not want to bother the user, save the key in a text file within your applicationdata subdirectory, and load it upon launch.
Thanks Michel,
What I meant was - This works fine for the first time the app is run, but from the second running onwards, the enterKey field will not exist because the database was created upon first run, and therefore the user does not need to enter a password on future occasions.
I can’t really save enterKey as a text file after they first enter the 9 digits either, because that file could be deleted or read by a non-authorised user.
Hope that made more sense.
[quote=81214:@Richard Summers]Thanks Michel,
What I meant was - This works fine for the first time the app is run, but from the second running onwards, the enterKey field will not exist because the database was created upon first run, and therefore the user does not need to enter a password on future occasions.
I can’t really save enterKey as a text file after they first enter the 9 digits either, because that file could be deleted or read by a non-authorised user.[/quote]
In your original code, you hardcoded the key, so your program found it within itself : EncodeHex(MD5("123456789"))
In order to do away with the need to encode every copy of your program, you need to first create the key to create the database, and then have it upon every start to use the database. So you can either request it from your customer via the enterKey field, or you save an encrypted file containing it, load it and decrypt it each time your app starts.
Basically, instead of storing the key within your code EncodeHex(MD5("123456789"))
, you can store it into your user brain, or within an encrypted file. Does it make sense ?
The issue of having the file deleted by the user can be solved by checking if it is there first, and if not, present a request for the user to enter his key. You should anyway make it plain when he enters it the first time around that he must make sure to remember it, as you have no way to guess if he was to loose it. It will be the user responsibility to keep the key, the same way it would have been yours if you had customized every copy.
So basically I have the following options:
-
Ask for password input every time (from their memory), and use that to decrypt the database.
-
Save userKey as an encrypted text file, and then load that in and decrypt it, each time the app is run thereafter.
Thank you very much Michel - I appreciate all your help 