View Single Post
  #19  
Old April 17th, 2008, 09:59 AM posted to microsoft.public.access.forms,comp.databases.ms-access
The Frog
external usenet poster
 
Posts: 10
Default Advice on securing a sensitive Access database

Hi Les,

We have a lot of points here to cover, so bare with me as I attempt to
work through them for you one by one:........

The AES key for each table was stored as a table property with DAO
code, encrypted Asymmetrically (public / private), for each user that
had access to the table.



Why a table property rather than as a separate table? Just to make
it
not so obvious?


***Answer: The reason for this was more of a matter of design
philosophy. You could also do this as a table. I preferred to make the
system as difficult to duplicate as possible. That being said an
experienced Access Programmer would still be able to locate the extra
table properties. It just helped to rule out the 'middle' level users
who know enough to be a bother but not enough to be a serious threat.
The security of the data ultimately does not depend on the obfuscation
of the key storage, but rather on the strength of the ciphers used.


1. Relevant tables in the data mdb are individually encrypted by
encrypting each relevant field.


What I did here was to build a function that wasa used for both
encryption and decryption of a field,


The same function to do both?


*******Answer: With symmetric encryption the same function is used for
both encryption and decryption purposes. You really only need one
function here, but if you wish to make the code more understandable
you could always create two functions, or use an object (as done in
one of the implementations that yields a class module) so that you
have three properties of the class, one for the AES key, and one for
each the encrypted and decrypted data (plaintext and ciphertext). You
could build in functionality so that if the value stored in the
encrypted property was changed by placing a new value from the app to
the object that the decrypted would automatically reflect the change.
I chose to ditch the class module in favour of a function (If I
remember correctly......).


Effectively you can choose how many AES keys are used for securing the
data. I used one AES key per table.



A *different* key for each table?

****Answer: Yep, exactly that, a different key for each table :-)



An Access question: Could controls not be bound to the decrypt

function?

****Answer: It depends on your design philosophy. I chose to use code
to control every aspect of each form and report. This made for a
little more work in the construction of the forms, particularly with
regards to list boxes and the like, but in the end the functions
needed to populate the controls with appropriately decrypted data only
had to be written once, and then called from the form (again by code)
to actually fill the control with the decrypted data. There are a
myriad of ways you could approach this, so it really is just a matter
of working out one that suits the design of your app and reverse
engineering it into the existing forms, reports, etc...


That is OK to check one user's key being copied to an other table. What

about one user's key being copied to the same table under a different
user's name?

Storing an encrypted copy of the table name and the user name
together
with the key should stop that.

Don't you also need to check in the same way in case the property has
been copied on the same table for a different user?


****Answer: Because of the private key / public key way of enciphering
the tables AES key, only the correct private key will decrypt a users
enciphered AES table key. This means that if a user duplicates another
users table key and renames it for themselves (lets say), then it
still wont help them unless they possess the specific private key for
the table key they copied. Their own private key is unique to them and
so wont work with anyone elses public key encrypted data. It only
works for data that is (in this case the table key) that is encrypted
with their matching public key. The key pairs are unique, and as such
the protection of the private key is really important, hence also my
comments on keeping the private keys out of the system if possible.


I wonder if some hardware would help. Fingerprint reader? (I have no

idea how secure they are)


****Answer: With regards to using hardware for storing the private
keys and also for biometric authentication you need to look around at
this stuff. There are a lot fo rubbish components on the market and
very few that are actually reliable AND secure. One of the best that I
have seen for securely storing keys was from Rainbow Technologies
(this is not a product endorsement, but rather an endorsement of the
type of approach used by this technology) - they had / have a product
called the iKey that acted as a storage container, a very secure one,
for keys / certificates, and if I remember correctly they also had a
model that could do cryptographic calculations. It was basically a USB
key, so no special hardware was needed on the computer with the
application, just some drivers. I saw this about ten years ago now, so
I would expect that today there are many versions of this sort of
thing available. If you can find one that has a simple to administer
system for creating / removing users and keys, and can be integrated
into your app without too much hassle then I would certainly entertain
the idea. It was what I wanted to do with the app I built. I was
hoping to find a USB key, with the ability to store the Public key for
a user as well as have it password protected on the key, and with an
integrated fingerprint/thimbprint reader. This would have been a nice
tri-factor authentication system. Cost is also a factor here too, some
of these things can be pretty expensive from memory.

I have also seen keyboards that have integrated smart card readers
(credit card tpe cards with smart chips on them) and finger /
thumbprint readers. I have also heard of software that can tell who
you are by just the way you type on the keyboard. Voice is another
possibility, but of course it can be recorded.

A passing thought on security here too. If your data is **REALLY**
sensitive, and the possibility exists that a user may be co-erced by
force into accessing the system / information, you may want to think
about placing a dummy table with false data that LOOKS real enough.
What you do is to have the user enter their password backwards or
something like that when under duress, and on login check it, and if
the password is entered backwards then only show the rubbish fake data
- but make the application look like it is working perfectly. At the
same time send a message to someone to let them know of the intrusion
and duress situation. Pretty extreme and certainly not an everyday
thing, but I have seen situations where this is necessary.


Don't understand "keeping the users private key out of the system"


****Answer: I think we covered this above, but again briefly it comes
down to a matter of adequately securing the system. The private /
public key pairs are the core of getting access to the tables AES
keys. What we need to do to really make it safe is to keep the private
key as secure as possible. Because the private keys, in the model I
ended up deploying, are stored in the database itself (although
encrypted), they represent a risk to the security of the system. Even
though the encryption is strong (AES 256), the password that the user
chooses becomes the weak point - it could be guessed or forced from
the user - and hence the private key becomes available - hence the
data becomes available. By keeping the private key separate
completely, it does not matter if the user password is guessable or
not - you are just eliminating risk from the system design.

If you use longer passwords as a minimum then users tend to write them
down or use easily rememberable phrases that can be guessed. This goes
back to the point about tri-factor authentication. That is considered
by many to be very strong, but even dual factor would provide a
massive increase in the level of security for the application - in
this case username/password (something you know) and a separate device/
storage for the private key (something you have). The 'something you
are' part would put the icing on the cake so to speak.

So in short, storing the private keys is the weakest point in my
existing app, due to the fact that a users password may be obtainable.
Keeping the private keys out of the system goes a long way to
eliminating this deficiency, and having a biometric pretty well
completes it. Another possibility would be to require two users to
authenticate themselves before the system was functional, and there
are cryptographic methods that can achieve this. Its all a matter of
approach. How far do you want to go to protect the data? What is the
cost of having unauthorised access? Basically you need a risk analysis
to figure out how far to go. There is always another level of security
you can add, the trick is knowing how little is too little and how
much is too much.



What have we achieved? The Asymmetric private key still has to be made

available. (from the third posting)

****Answer: That is exactly correct, the private key for the user
needs to be made available to the user when they perform a successful
login. Only then should the users private key be available to them and
the application. The public key can be seen by anyone so it doesnt
really matter.

The users private key is NEEDED to obtain and decrypt the tables AES
key. Thats why we have a copy of the AES key encrypted with table for
each user, using each users unique public key.

I think what you missed here was that each user gets a unique public /
private assymmetric key pair. Only the AES key is common, and only
then on a per table basis. Its kind of like having a lock box for each
user, and each lock box has a unique key that only that user has.
Inside each lock box is another key, lets say to the beer fridge :-).
If I take my lock box, using my key and open it, then I can get access
to the beer fridge key and hence the beer. If however I take my key,
and I try and use it to open another users lock box it wont work
because it needs that users key and not mine - so I cant get the berr
fridge key and hence no beer :-(

What we have in this design is the same beer fridge thinking for each
table, in effect a series of independantly locked beer fridges - the
key from one beer fridge wont open another fridge. We have for each
fridge a set of lock boxes, one for each user, each secured with the
users lock (same lock for one user across all of their lock boxes).
The user can take their key, open their lock box if they have one for
a specific fridge, then take the key to the fridge and get some beer.
The user cant open another users lock box, and they cant take a key
from one fridge and use it in another fridge. BUT, because the user
has only a single key for all of their lock boxes (and hence all the
fridges that they can get beer from because they can get the fridge
key), it is very important to protect the users private key. That
private key in this analogy is the unique user private key they obtain
when they log in, and in my app is stored in the back end database -
and hence also my strong desire to keep the key away from the database
and potentially weak passwords.

I hope this helps a bit. I know this can be a tricky area to deal
with. As I said before, the application of the cryptography is the key
to success here. Its worth taking a little extra time to get the
details worked out for the implementation. The algorithms are actually
only useful if they are applied in a secure system design. The most
common cryptographic mistake I have seen is people using really
capable algorithms and really poor system design - effectivley putting
a steel door on the front of the home and a fly wire screen on the
back. If you can get the private keys out of the application /
database and store them separately and securely then do it!

Cheers

The Frog