Advice on securing a sensitive Access database

L

Les Desser

I wonder if someone could give me some pointers on the following.

I need to securely encrypt an Access 2003 database currently sitting on
a server with multiple users linking to it from their individual PCs via
an Access 2003 front-end.

I need a hardware/software solution that will:-

1. Encrypt the database on the server so that a copy of it is of no use
to anyone. This is to cover if the server is stolen.

2. Ensure that only authorised users directly connected to the network
can access the database and preferably only via the designated Access
front-end database.

3. Authorised users cannot get a decrypted copy of the file via their
PCs - i.e. cannot use Explorer or similar to copy the file in decrypted
form.

I presume that the solution would include hardware and software
elements.

I would be grateful for any guidance.

Many thanks.
 
K

Keith Wilby

Les Desser said:
I wonder if someone could give me some pointers on the following.

I need to securely encrypt an Access 2003 database currently sitting on a
server with multiple users linking to it from their individual PCs via an
Access 2003 front-end.

I need a hardware/software solution that will:-

1. Encrypt the database on the server so that a copy of it is of no use
to anyone. This is to cover if the server is stolen.

2. Ensure that only authorised users directly connected to the network
can access the database and preferably only via the designated Access
front-end database.

3. Authorised users cannot get a decrypted copy of the file via their
PCs - i.e. cannot use Explorer or similar to copy the file in decrypted
form.

I presume that the solution would include hardware and software elements.

I would be grateful for any guidance.

If your data is really that sensitive/valuable then I would suggest using
Oracle or similar since Access security can be easily broken.

Keith.
www.keithwilby.com
 
M

MikeB

Keith Wilby said:
If your data is really that sensitive/valuable then I would suggest using
Oracle or similar since Access security can be easily broken.

There is another venerable DB that is used daily by the US Army, Airforce,
Navy and the FBI for the one of the very reasons you seek. After all, it was
originally invented to track the engineering data and the parts to the Space
Shuttle by Boeing, then later ported to the PC environment. I have used it
since 1983 and quite a few of my colleague developers use it for medical
records applications which require a similar security requirement.

www.RBase.com

Still very much alive and used worldwide where other solutions can't make it
work.
 
L

Larry Linson

As far as I know, there is no security that can be applied via Access itself
that will fulfill your requirements with an "Access" (Jet or ACCDB)
datastore. Access Workgroup Security is no longer supported for Access
2007's standard ACCDB and ACCDE; software to de-secure an Access MDB for
versions prior to Access 2007 can be found, freely downloadable, by
searching the Internet; the encryption provided by Access itself only
prevents reading from outside Access (e.g., to stop someone exploring with a
low-level disk reader/dump program). Access' encryption is not customized to
the database and can be read by any copy of the same version of Access, or
the Access runtime.

The normal approach for extremely sensitive data is to store it in a server
database; Access can be used as a client application, either with MDB
connectivity via ODBC to any ODBC-compliant server DB, or (with MS SQL
Server only) via the ADP, aka Access Project, via OLEDB (however, my
understanding is that security with ADP has flaws, too, and is not
recommended by knowledgeable users for sensitive data). Then, you can use
the security provided by the server database, and the network itself -- and
on those issues, you would need to find an appropriate newsgroup for the
server database and network security, or vendor sites, to determine if the
combination can meet your requirements.

A generally accepted axiom, in regards to encryption and security with file
server databases such as Access, is that if you allow someone access to your
database, or they have it in their hands, any security you apply can be
broken. The availability of "cracks" in the "warez" world for very
expensive software packages distributed to users confirms this -- the
manufacturers and vendors of software packages costing tens of thousands of
dollars or more per copy certainly have adequate incentive to protect that
software in the most secure way from unauthorized access, and just can't
manage to defeat the "warez phreaks" who take security as a challenge (often
providing their cracks for free, just to demonstrate that they can). Many of
those cracks, illegal though they may be, do work as advertised, to the
dismay and chagrin of the people who sell the software to which they give
unlimited access.

I regret that I don't have more encouraging words for you.

Larry Linson
Microsoft Office Access MVP
 
L

Les Desser

[...]

Thank you for your comprehensive response.

Also thanks to the other posters for their ideas.

The background is that the Access application has been developed over
many years and it is not really viable to re-write it.

Due to the prospect of some commercially sensitive data being now stored
in the database, it has become desirable to secure the data.

I do not have major concerns about the Access front end as

1. the staff using it are trustworthy
2. the data would have to be extracted table by table
3. the front-end is an MDE and I think I can securely (reasonably) hide
the table view.

To steal the data via the front end (or an alternative front end once
Access security had been broken) would be non-trivial and they would
have to work within the office (as the data would be encrypted).

My main concern is how to, on the one hand, encrypt the data on the
server (TrueCrypt?) so that if the server is stolen the data cannot be
read, and on the other hand, allowing the Access front end to read the
decrypted data but somehow blocking access to the decrypted data to the
Windows file copy facility.

As far as I can see, once the decrypted data is visible to the PCs
running the Access front end, it is also a matter of a few seconds to
copy the whole decrypted data mdb using Explorer.
I regret that I don't have more encouraging words for you.

Sounds like I have a problem :(
 
T

The Frog

Hi Les,

This is a problem that I have solved once before, and I can tell you
that it is fraught with dangers. I have managed to incorporate AES 256
bit encryption on the individual tables, complete with a user
control / access system. I must stress just how much a pain in the
arse this was / is.

The way that I achieved this was to use encryption the same way the
EFS does. Basically it works like this:

1/ You need to generate a *RANDOM* key to be used for the AES
algorithm for each table. I used GUIDs for this and adapted the GUID
to a key.

2/ You need to make a 'master' Asymettric key pair to act as a data
recovery in case of emergency. Use a different GUID.

3/ You take the 'master' key pair, and using the private key encrypt
the AES key for each table, and store the encrypted AES key as a table
property of your defining.

4/ Lock away the AES keys, as well as the 'master' key pair.

5/ At the field (contents) level you use the AES encryption, specific
to the table, to encrypt the contents of each field.

What you should now have is the entire database encrypted with AES
encryption. (I will try to find the links to the VBA code for this).
At this stage no user can access the data in any meaningful way,
unless they happen to have a neat way of breaking either the symmetric
encryption on the fields or the asymmetric used to encrypt the AES key
itself.

Now comes the user part:

For each user you need to generate an asymmetric key pair. This is in
turn used to make an encrypted copy of the AES key, which is attached
to the tables as a property with a name of your choosing. I suggest
the property name either be the user name / id, or some other easily
identifiable term that is specific to each user.

In this way you can also only give users access to the tables that
they need simply by making sure that you dont issue them with an
encrypted copy of the AES key for that table. I suppose you could
extend the model further even to the column / field level if you
wanted, but I thought that to be overkill.

I used the public part of the key pair to encrypt the AES keys, and as
per normal kept the private part private :) It was my intention to
eventually use certificates with a token to handle this but the
project never went that far.

Anyway, back on with the task at hand. We had two options for handling
the private keys with this. The first was to have them stored in files
on disk / usb key etc.., or alternatively to have them stored in a db,
themselves encrypted. We eneded up using the second system due to
practicality. Users were asked for a username / password to access the
system. The password was MD5 hashed, and in turn the MD5 hash was used
to decrypt the private key again using AES. The way that we knew if
the password was correct was to have the MD5 hash also stored in
encrypted format with the private key. This became the weak point of
the system, but as I said we didnt get to the point of using
certificates and tokens. If the username / password combo was able to
successfully decrypt the AES encrypted private key it would also
successfully decrypt a copy of the MD5 hash associated with that key.
This was done in a table with 3 columns, username, password, private
key.

The administration of this was done through a separate database / app
that was not accessable to anyone except the administrators. It was
kept on a secure usb key (if you can call them that). I am sure you
can think of ways of securing the physical media. User key pairs were
added as needed and expired / removed as needed.

I am sure that you could also implement time restrictions, as well as
network card or IP address restrictions to the application. For
example it is possible to gather the MAC address of a network card, as
well as the IP address of the card as a means of testing the 'local'
environment of the application, though I would have to think about how
you would secure / administer that data.

In the end it comes down to how far you want to go to secure the data
and is it worth it? The method described above will certainly give
your data a heavy level of encryption by most current standards, but
that does not necessarily mean that the model suits your purposes or
is suitable for the task.

The app I wrote is currently stored securely and I do not have access
to the finished code, however I do remember that I located a lot of
what I needed freely available on the net. I will have a look over the
weekend and see if I can locate the sites where the code came from for
the different algorithms.

Hope this gives you some food for thought.

Cheers

The Frog
 
L

Les Desser

"paii said:
I have not used any strong DB security; but as others have pointed out,
someone with physical access to your serve can with time break any
encryption you apply. You need secure the server, at least in a locked room
in a building with some type of monitored alarm system. That way your random
thief would only get basic office equipment. Using Windows security; your
server hardware may be the only thing of value to an office equipment thief.
A more sophisticated thief may only take your backup media or better yet,
break-in though the internet.
I accept your comments and recommendations. My main problem still
exists even when physical security of the server has been addressed.
 
L

Les Desser

<[email protected]>, The

[snip fine detail]

Phew! I have given it a quick read and there is a lot there that I do
not understand at this stage, but it gives me hope that a possible
solution is appearing.
I will have a look over the weekend and see if I can locate the sites
where the code came from for the different algorithms.
That would be most useful.
Hope this gives you some food for thought.

Thank you - it gives me hope.
 
T

The Frog

Hi again Les,

Security is depth is certainly the best way I can think of to approach
the issues surrounding any data confidentiality. There are many
factors to consider when approaching such a thing, and most of them
are situation dependant on how you address them. For this you need to
do a proper risk analysis, which I think is probably going beyond the
scope of this forum. If you want to approach such a thing I am happy
to try and steer you in the right direction, so just drop a note in
the forum here.

As for the 4k keys, you must understand that there is a difference in
cryptographic types (algorithms) used. Symmetric and Asymmetric. AES
is a symmetric cipher, commonly used with a 256bit key strength. A
symmetric cipher, in this case AES, is quite fast, safe, and
considered strong for securing information, but it suffers, like all
symmetric encryption, from a problem known as the 'Key Distribution
Problem'. Basically it means that you use the same key to encrypt and
decrypt the data. If you want to send the data to someone with a
symmetric cipher then in order for them to decrypt it they need to
know the same key you do - but you shouldn't transmit the key with the
data! So how do we get around this problem?

The answer lies in Asymmetric encryption. Asymmetric encryption allows
us to have a public and private key which are distinct and separate
from each other, but at the same time directly related to each other.
The way it works is that you can encrypt something with your Private
key (called signing in most instances), and anyone can acquire (safely
and without concern) a copy of your public key and see that the data
came from you. Only your public key can be used to decrypt the data
encrypted with the private key. Now if we reverse the situation, and
we encrypt the data with the public key, only the private key can
decrypt it, which means that anyone can encrypt something, send it to
you, and only you with the private key can decrypt it.

The difference between the two keys is one of information. The private
key contains enough information to be able to reproduce the public key
at will, but the public key is built in such a way that to reproduce
the private key is extremely difficult (but not impossible!). So, what
do we do to make the public key really secure? We use giant 4k keys
that make the problem so large / hard to solve that for all intents
and purposes it is unbreakable / considered secure. The problem with
Asymmetric encryption is that it is slow by comparison to Symmetric.
Slow by a long way.

So how do we solve the problem of your DB encryption? We use
Asymmetric to encrypt the Symmetric keys. The 'heavy lifting' of
encryption / decryption of the data is actually handled by the AES
cipher which is relatively fast, and only the decryption of the AES
keys is done with the slower Asymmetric cipher. This keeps the system
and data both relatively fast and safe, and also gets around the key
distribution problem.

So, crash course in cryptography aside, here are some links that I
have used for the different algorithms and components:

MD5 http://www.di-mgt.com.au/crypto.html#MD5
RSA http://www.di-mgt.com.au/crypto.html#dhvb
AES http://www.frez.co.uk/freecode.htm#rijndael

You will also find some useful code implementations here:
http://www.freevbcode.com/ShowCode.asp?ID=3779

I hope that this gets you on your way, and you are successful in
implementing this for your needs. I will monitor this thread if you
need further help with this.

Cheers

The Frog
 
L

Les Desser

<fcebdacd-2bd8-4d07-93a8-8b69d3452f3e@s50g2000hsb.googlegroups.com>, The

[snip detail]
So, crash course in cryptography aside,

Thank you for that. It was very clear and I actually understand it!
here are some links that I have used for the different algorithms and
components:

Thank you for all that. I will go through them in the next few days, but
it is your first post that I still need to study.

Thanks also for your kind offer of help.
 
M

Mr.Frog.to.you

Hi Les,

I also found the code for the GUID creation, courtesy of Trigeminal. I
have used this in Excel and Access before and it seems to work
fine :)

Enjoy

'------------------------------------------
' basGuid from http://www.trigeminal.com/code/guids.bas
' You may use this code in your applications, just make
' sure you keep the (c) notice and don't publish it anywhere
' as your own
' Copyright (c) 1999 Trigeminal Software, Inc. All Rights Reserved
'------------------------------------------


Option Compare Binary


' Note that although Variants now have
' a VT_GUID type, this type is unsupported in VBA,
' so we must define our own here that will have the same
' binary layout as all GUIDs are expected by COM to
' have.
Public Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type


Public Declare Function StringFromGUID2 Lib "ole32.dll" _
(rclsid As GUID, ByVal lpsz As Long, ByVal cbMax As Long) As Long
Public Declare Function CoCreateGuid Lib "ole32.dll" _
(rclsid As GUID) As Long


'------------------------------------------------------------
' StGuidGen
'
' Generates a new GUID, returning it in canonical
' (string) format
'------------------------------------------------------------
Public Function StGuidGen() As String
Dim rclsid As GUID


If CoCreateGuid(rclsid) = 0 Then
StGuidGen = StGuidFromGuid(rclsid)
End If
End Function


'------------------------------------------------------------
' StGuidFromGuid
'
' Converts a binary GUID to a canonical (string) GUID.
'------------------------------------------------------------
Public Function StGuidFromGuid(rclsid As GUID) As String
Dim rc As Long
Dim stGuid As String


' 39 chars for the GUID plus room for the Null char
stGuid = String$(40, vbNullChar)
rc = StringFromGUID2(rclsid, StrPtr(stGuid), Len(stGuid) - 1)
StGuidFromGuid = Left$(stGuid, rc - 1)
End Function


Cheers

The Frog
 
L

Les Desser

I also found the code for the GUID creation, courtesy of Trigeminal. I
have used this in Excel and Access before and it seems to work fine :)

Thank you.

I have read trough your first post again and am having some difficulty
understanding it all.

It would be helpful to get an overview of what is being achieved.

For starters, is the following correct?

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

2. Decryption keys are stored, encrypted, in the front-end db (does it
have to be separate from the application front-end?)

3. Access to the decryption keys is controlled by some user entered
password.

4. It seems obvious that any field that has been encrypted can no
longer be directly bound to an Access control. It must be displayed via
a function and updated by code.

Point 4 is not a problem as it is only limited data that needs
encryption.
 
M

Mr.Frog.to.you

Hi Les,

Lets see if we can go through this step by step so to speak. I will
attempt to answer each point in turn as we go, and expand on the
actual methodology I 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, based on the AES algorithm.
Effectively you can choose how many AES keys are used for securing the
data. I used one AES key per table.

I applied the function to encrypt / decrypt such that any data read
from the table was unintelligible without decrypting it through the
function, and in turn no data was written to the table without being
encrypted with the function. In this way each field was encrypted with
the same AES key. This was done through unbound forms and code. The
end user never actually saw the encryption taking place.

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. Each users public key was used to encrypt a
copy of the AES key for the table and store that as the value for the
property. Only the users private key would be able to decrypt the copy
of the AES key stored as a property specific to that user (eg/ I made
a table property with the same name as the username, and stored the
encrypted (users public key) form of the AES key as the value of that
property).


2.  Decryption keys are stored, encrypted, in the front-end db (does it
have to be separate from the application front-end?)

I actually kept all the encryption keys stored in the back end, and
only the functionality to use them in the front end. This way the
front end never really needed changing once the encrypt / decrypt
functionality had been built in.

Everything stored in the backend db was in ciphertext (encrypted
form). This way it did not matter if someone stole a copy of the
backend db, it was effectively useless. If they connected via code
from a different application to try and read the data all they would
get is meaningless rubbish from each field.

I made a third application specific to the front end / back end
application that was specifically used to administer the cryptography.
In this third application I had the ability to connect to the back end
and add users (and the associated encrypted keys) to the tables. In
this Crypto Admin app I kept stored the AES keys for the tables, as
well as the public and private key pairs for each users asymmetric
keys. I also kept a 'master' public / private key pair, which I
associated the same as a user, to each table. This was a type of
failsafe in case I had to do some form of data recovery. The master
user had no login to the normal application though. In theory you dont
actually need it because you have the AES keys anyway, so you could
leave it out.

I also built a function into the Crypto Admin application to be able
to dump the data into a non encrypted database if necessary. I was
never truly comfortable with the function as I felt that it was
dangerous to have this potentially in the wrong hands, but the bosses
wanted it (sigh).

I also made sure that I had a log table built into the backend, and
into the crypto admin app, so that all user activity was recorded. I
dont know if you need to go this far or not, but it is a useful idea
if you are tracking attempted breaches. I kept the Crypto Admin
application completely separate from the network, it lived (lives) on
a secure (password to access) USB key, and a backup of the AES keys is
printed out and stored in a safe, along with a copy of all the code,
and a CD with empty versions of the finished apps.

Oh yeah, I almost forgot. I also built in to the Crypto Admin app the
ability to change the AES keys for each table in case they were felt
to be compromised. I did this by having the app simply create a new db
with the appropriate table structures, and then quite literally read
each row from the source, decrypt it with the old key, encrypt the
data with the new key, and store it in the new backend db. Needless to
say this was a time consuming process but a nice safety feature to
have.
3.  Access to the decryption keys is controlled by some user entered
password.

The user access to each table was done via checking if the user had a
table property in their name, with a stored AES key value. This was
also able to be checked for validity (ie/ to see if someone had just
copied the property from another table).

The way the user asymmetric keys were used is as follows. Bare with me
it takes a little to go through it.

1/ A Private / Public key pair is generated for a user in the Crypto
Admin application.
2/ The user is (in the crypto admin app) 'assigned' the tables that
they are allowed to access
3/ For each table that the user is allowed access the users public key
is used to encrypt the appropriate tables AES key, which is then
stored as a table property using the users name as the property name.
4/ The users stored encrypted copy of a tables AES key can be checked
for validity by either using the decrypted AES key to decypher a known
value and see that it is true (such as a table property that holds a
copy in encrypted form of the tables name), or by placing a MD5 hash
value with the stored AES key that matches the users name or password
or some other known value. I went with the latter, but the former is
probably easier to do.

Actually if I were to do this again, I would make a table property and
store an MD5 hash of the tables name in it, encrypted with the tables
AES key. When a user tries to access the table the form (code) checks
to see if the user has an associated table property in their name,
then uses the users private key to decrypt the stored encrypted AES
key, then uses the AES key to decypt the stored MD5 hash (the known
value) and checks this against the MD5 hash generated at runtime for
the tables actual name. If they match then the user is valid for the
table, if the MD5 hashes dont match then something has either gone
wrong or someone has copied the username / stored value from another
table and is using it to try and break the table in question.

This way, with code, you can assign different users access to
different tables without fear that because they have access to one
area of data that they could access other areas that they may not be
allowed to.

The Crypto Admin part was to assign these users to the tables and
associate the keys properly. It made life a lot easier than trying to
do this through the front end, and allowed the private keys and AES
keys another layer of security by never having them directly available
to the 'public'.
4.  It seems obvious that any field that has been encrypted can no
longer be directly bound to an Access control.  It must be displayed via
a function and updated by code.

This is absolutely correct. I would recommend doing the encryption
control through a third application as I talked about above. Use code
for everything that needs encryption, and hard code the needed
functionality into the front end. Keep the admin separate from the
front end, and keep the data in the back end.


I hope this helps clear this up a little. As I said it was a pain to
do this. The weak point as I mentioned earlier was in the storage of
the usernames and passwords (with the private keys). I was giving this
a little thought since your first post, and *maybe* have a better way
to do it than the one I first used.

It occurs to me that it would be better to keep the usernames
completely obfuscated if possible so that it makes things very hard
for someone to be able to reverse engineer them. For this you could
use again MD5 hashing. for the users login, they would type their
username and password. Both the username and password are MD5 hashed.
The front end checks a table in the back end for a matching value for
the username. If this is found then the password MD5 hash is used as
an AES key to decrypt the users private key, and some known value
check for validity same as mentioned before.

As with all cryptographic applications, it is a complex task to get it
right. Even the best cryptographic ciphers can be undone by poor
system design (think Enigma in WW2). In this case the weakest point as
I see it is the username / password area used for the login to get the
users private key. If you are able to overcome that with a better
system design then go for it. I would recommend it if the data is
truly valuable. The best you could realistically go for here is tri-
factor security, something you have (a token), something you know
(username / password), and something you are (biometric). Might be
overkill, but keeping the users private key out of the system would
make this application really strong. If you can get to the dual factor
level that would be brilliant for most purposes.

Hope this helps

Cheers

The Frog
 
L

Les Desser

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?
 
L

Les Desser

The said:
So how do we solve the problem of your DB encryption? We use Asymmetric
to encrypt the Symmetric keys. The 'heavy lifting' of encryption /
decryption of the data is actually handled by the AES cipher which is
relatively fast, and only the decryption of the AES keys is done with
the slower Asymmetric cipher.

Not sure if I quite follow that.

1. Data encrypted by AES key

2. AES key encrypted with Asymmetric public key (?)

3. AES key decrypted with Asymmetric private key (?)

4. Data decrypted by AES key

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

I'm sure your previous post has the answer to this, but I can't quite
see it.
 
L

Les Desser

"(e-mail address removed)" <[email protected]> Wed, 16
Apr 2008 01:24:04 writes

(As I worked through your notes, later parts answered some earlier
questions. I have removed some but may have left some others by
mistake)
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?
based on the AES algorithm.
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?
I applied the function to encrypt / decrypt such that any data read
from the table was unintelligible without decrypting it through the
function, and in turn no data was written to the table without being
encrypted with the function. In this way each field was encrypted with
the same AES key. This was done through unbound forms and code. The
end user never actually saw the encryption taking place.
An Access question: Could controls not be bound to the decrypt
function?
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. Each users public key was used to encrypt a
copy of the AES key for the table and store that as the value for the
property. Only the users private key would be able to decrypt the copy
of the AES key stored as a property specific to that user (eg/ I made
a table property with the same name as the username, and stored the
encrypted (users public key) form of the AES key as the value of that
property).
So we have each user with their own encrypted copy of the key.
I actually kept all the encryption keys stored in the back end, and
only the functionality to use them in the front end. This way the
front end never really needed changing once the encrypt / decrypt
functionality had been built in.
Understood

Everything stored in the backend db was in ciphertext (encrypted
form). This way it did not matter if someone stole a copy of the
backend db, it was effectively useless. If they connected via code
from a different application to try and read the data all they would
get is meaningless rubbish from each field.

[... balance of notes left for later digestion..]
The user access to each table was done via checking if the user had a
table property in their name, with a stored AES key value. This was
also able to be checked for validity (ie/ to see if someone had just
copied the property from another table).

The way the user asymmetric keys were used is as follows. Bare with me
it takes a little to go through it.

1/ A Private / Public key pair is generated for a user in the Crypto
Admin application.
2/ The user is (in the crypto admin app) 'assigned' the tables that
they are allowed to access
3/ For each table that the user is allowed access the users public key
is used to encrypt the appropriate tables AES key, which is then
stored as a table property using the users name as the property name.
4/ The users stored encrypted copy of a tables AES key can be checked
for validity by either using the decrypted AES key to decypher a known
value and see that it is true (such as a table property that holds a
copy in encrypted form of the tables name)

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.
, or by placing a MD5 hash
value with the stored AES key that matches the users name or password
or some other known value. I went with the latter, but the former is
probably easier to do.

Actually if I were to do this again, I would make a table property and
store an MD5 hash of the tables name in it, encrypted with the tables
AES key. When a user tries to access the table the form (code) checks
to see if the user has an associated table property in their name,
then uses the users private key to decrypt the stored encrypted AES
key, then uses the AES key to decypt the stored MD5 hash (the known
value) and checks this against the MD5 hash generated at runtime for
the tables actual name. If they match then the user is valid for the
table, if the MD5 hashes dont match then something has either gone
wrong or someone has copied the username / stored value from another
table and is using it to try and break the table in question.
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?
This way, with code, you can assign different users access to
different tables without fear that because they have access to one
area of data that they could access other areas that they may not be
allowed to.
Makes a lot of sense
The Crypto Admin part was to assign these users to the tables and
associate the keys properly. It made life a lot easier than trying to
do this through the front end, and allowed the private keys and AES
keys another layer of security by never having them directly available
to the 'public'.


This is absolutely correct. I would recommend doing the encryption
control through a third application as I talked about above. Use code
for everything that needs encryption, and hard code the needed
functionality into the front end. Keep the admin separate from the
front end, and keep the data in the back end.


I hope this helps clear this up a little. As I said it was a pain to
do this. The weak point as I mentioned earlier was in the storage of
the usernames and passwords (with the private keys). I was giving this
a little thought since your first post, and *maybe* have a better way
to do it than the one I first used.
It occurs to me that it would be better to keep the usernames
completely obfuscated if possible so that it makes things very hard
for someone to be able to reverse engineer them. For this you could
use again MD5 hashing. for the users login, they would type their
username and password. Both the username and password are MD5 hashed.
The front end checks a table in the back end for a matching value for
the username. If this is found then the password MD5 hash is used as
an AES key to decrypt the users private key, and some known value
check for validity same as mentioned before.

As with all cryptographic applications, it is a complex task to get it
right.

Say that again!
Even the best cryptographic ciphers can be undone by poor
system design (think Enigma in WW2). In this case the weakest point as
I see it is the username / password area used for the login to get the
users private key. If you are able to overcome that with a better
system design then go for it.

I wonder if some hardware would help. Fingerprint reader? (I have no
idea how secure they are)
I would recommend it if the data is
truly valuable. The best you could realistically go for here is tri-
factor security, something you have (a token), something you know
(username / password), and something you are (biometric). Might be
overkill, but keeping the users private key out of the system would
make this application really strong.

Don't understand "keeping the users private key out of the system"
If you can get to the dual factor
level that would be brilliant for most purposes.

Hope this helps

Very much so! I am at the stage that as I work through your notes I
think I understand each step but I cannot say I have a clear picture in
my head of all the steps. I need to re-read a few more times.
 
T

The Frog

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.

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 :)


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...

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.

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.


****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.


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
 
L

Les Desser

Needless to say this was a time consuming process but a nice safety
feature to have.

I know this is really an "impossible" question to answer accurately, but
....

What sort of effort - in man days - should this project take in Access
for an experienced Access developer (ignoring research on the cryptology
side).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top