WebApp Sec mailing list archives

RE: Cryptography and Site Security: Please critique my security idea


From: "Brass, Phil (ISS Atlanta)" <PBrass () iss net>
Date: Thu, 27 Mar 2003 21:02:58 -0500

Obviously this is a vendor-specific solution on the server side, but
what if you used IIS and w2k or .NET server with encrypting file system,
and either SSL client certificates (optionally in one of those cool USB
hardware tokens) or else at least using HTTP authentication.  Now the
attacker won't be able to download the encrypted files unless they
compromise a user account.  And there's no weirdness with file "1" that
contains everybody's keys.

I may be wrong, but it sounds like you're reinventing the wheel...

Phil

-----Original Message-----
From: Jim McGarvey [mailto:jim.mcgarvey () interblink com] 
Sent: Thursday, March 27, 2003 7:14 PM
To: Robert Paris; webappsec () securityfocus com
Subject: Re: Cryptography and Site Security: Please critique 
my security idea


Hi Robert,

My comments are below in your e-mail.  Hopefully I haven't 
stated anything that is glaringly incorrect, but we'll see 
after others on the list weigh in.  In general I like your 
idea, at least from a theoretical standpoint.

-Jim

----- Original Message -----
From: "Robert Paris" <rpjava () hotmail com>
To: <webappsec () securityfocus com>
Sent: Thursday, March 27, 2003 7:05 AM
Subject: Cryptography and Site Security: Please critique my 
security idea




My company is going to have an application that houses and shares 
internal documents through an extranet. There has been a concern by 
the network administrators that even with a firewall, someone might 
get direct access to the server (housing these documents) whether 
through hacking or otherwise. If they did, they'd have 
access to all 
the documents. So I came up with the following solution, which I'd 
like some critique on:

1. A symmetric (secret) key ( Key "A" ) is created
2. All files to be managed are encrypted with key "A"

So if I understand correctly, you are going to encrypt every 
file on the server with the same symmetric key.  Since you 
didn't specify, I'll assume this means you're using a 
symmetric encryption algorithm, like RC4, with a standard 
sized symmetric key, say 128 bits.

You state that you are trying to protect the contents of the 
files in the event the server is compromised.  In general I 
would not advise encrypting every file with the same 
symmetric key.  It probably depends on your encryption 
algorithm, but most would be quite susceptible to being 
compromised if used in this manner.

If an attacker gets into your server and downloads all of the 
encrypted files, if he knows or can guess the decrypted 
contents of any of the files (say one of the files that 
happened to be encrypted with your "Key A" was 
allyourbase.swf, a large file whose decrypted contents can be 
easily found on the Internet), then he is one step closer to 
being able to decrypt every other encrypted file he has downloaded.

Take RC4 for example.  The encryption method basically uses 
your key, "Key A," to generate a pseudo-random byte stream, 
which it then XOR's with the real data to produce encrypted 
data.  But if "Key A" is the same for every file, the 
pseudo-random byte stream is always the same.  So if the 
attacker has an unencrypted copy of any of the encrypted 
files (allyourbase.swf, for example), he can simply XOR the 
encrypted and unencrypted versions together, and he then has 
the first part of the pseudo-random byte stream (up to the 
size of that file, say 800 Kbytes).  Now he can decrypt the 
first 800 Kbytes of any encrypted file by XORing the byte 
stream he now knows with the encrypted file.  If he is very 
clever or the encryption algorithm is weak (or the key is 
weak), he may even be able to determine what you're using for 
"Key A" based on what he now knows.

3. Each user is assigned an asymmetric (public-private key pair)
   key ( Key "B" )
   a. The user is assigned this key pair, but NOT given the key. We
      house the key internally.
4. Key "A" is encrypted separately for each key "B" ( called
   file "1" )
5. User is given file "1"
6. The public key for each user's private key is stored on 
an internal
   server that is inaccessible from the server and vice 
versa 7. When 
the app/web server is started up, the application is in a
   "turned off" state. This is because no public keys have loaded.
   There is one page only that is accessible and it is locked to two
   IPs (both internal). This page allows an authenticated user to
   upload the public keys in to applciation memory. This must happen
   after every restart or the site is unusable.

I think what you're calling a "public key" I usually think of 
as a "private key" because that's the one you want to keep a 
secret.  The key you used to originally encrypt Key "A" into 
file "1" doesn't need to be kept secret, so I would call that 
one "public."  But of course it works no matter how you name them.

8. The first time a user ever logs in to the site, they must give
   username, password and upload file "1". This file "1" 
(after being
   verified through message digest) is then stored in the user's
   cookie. After this, they log in with username and password.

That makes sense.  Two levels of authentication (password and 
encrypted key) makes it that much more secure.

9. After user log-in, file "1" is sent to the server, and 
opened with
   the proper public key (in memory) and stored in session memory
   only. During this session, if this user wishes to download a
   document, this now decrypted key "A" will be used to decrypt the
   file and send the decrypted stream to the user. The file remains
   encrypted on the server. As well, the in-memory key "A" 
is used for
   encryption when they upload a file.

This should effectively keep Key "A" from being written to 
the disk on the server, and only in memory during an open 
session, which is good.

10. All communication is HTTPS, 128.

As well, I am considering putting a lifespan on the 
private/public key 
pair that is used to encrypt the symmetric key that is stored 
(encrypted) in the user's cookie. What I would do (and I don't have 
this 100% down) is, if the lifespan is past, create a new key once 
(for that old key) and use that new key to encrypt the 
symmetric key 
and save that to their cookie. So even if they gave the 
original file 
to someone (along with username and pass), it'd no longer 
be useful. 
I'm not 100% sure how to make this work correctly or even if it's a 
good idea.

I think it's a good idea to expire key pairs.  I don't think 
you could do it on the fly with cookies, because you have the 
public key pairs stored on a separate server which this 
server can't access, so you would have no way to exchange the 
appropriate information.

I would just re-issue encrypted symmetric keys once every 
year.  Hand them out to users, and have a two week period 
where you upload both the old and new public keys to the 
server.  Then destroy the old public keys, and the old 
encrypted symmetric keys are forever useless.


Please let me know:
1. What are the weaknesses of this architecture?

I think the potential to break your symmetric encryption that 
I mentioned above is a weakness.

2. What performance hits will this cause?

It should be minimal, almost identical to the performance hit 
of SSL, since like SSL, your asymmetric encryption is only 
done on keys, and the bulk of the encryption is symmetric.  
So the performance hit is double that of just doing SSL, 
because you are doing both SSL encryption of transferred 
files and your own decryption of each transferred file.

3. What are some alternative/better ways to achieve this?

I can't think of any, though I feel this may be overkill 
unless you are protecting classified government 
information... and then you aren't allowed to build your own 
encryption without getting it approved by NIST.  I would hate 
to be the guy who inherits this system from you when your 
career takes you on to bigger and better things.  Chances are 
the first thing the next guy will do is blow away the entire 
system and do something else on his own... that's always how 
it seems to go.  So my personal suggestion is to try to keep 
things simple if possible, and consider carefully whether the 
risk is worth the cost (short term, long term, and ongoing 
management) of implementing a system like this.

However I do have one idea for dealing with the encryption 
weakness I suspect this system has.  Instead of encrypting 
every file with the same symmetric key (generating identical 
pseudo-random byte streams that could be determined by an 
intruder), find some way to vary the symmetric key on a per 
file basis.  For example, have a table on the server that has 
a second symmetric key unique for each file, then the 
symmetric key you actually use to decrypt the file (and 
originally to encrypt it) is the XOR of your Key "A" and the 
not-so-secret key in the table.

This ensures that every pseudo-random byte stream used to 
encrypt each file is unique.  So if someone knows the 
contents of one of the encrypted files, and uses that 
information to produce the byte stream used to encrypt the 
file, that information can't be used to decrypt other files.  
Assuming an strong encryption algorithm is used.  My 
experience tells me RC4 would probably be adequate, but if 
anyone knows otherwise please let me know.

The table of per-file keys could of course be discovered by 
an intruder, but that doesn't matter.  The only reason for 
doing this is to ensure every pseudo-random byte stream used 
to encrypt each file is unique.  Having the Key "A" XOR'd 
with the key from the table ensures that the symmetric key is 
still secret.

Or instead of a table of files and keys, you might be able to 
do some sort of hash of the filename to get a fairly unique 
key for the same purpose.


Some major concerns/limitations:
1. We must use the browser as the thin client and it may be 
IE/Netscape or even something else (as long as cookeis and 
HTTPS 128 
are enabled) on windows, linux, unix, mac/osX.

2. Our users will not be willing to do anything more 
inconvenient than 
that one time uploading of the encrypted key. And if possible to do 
less, they'd prefer this. Especially since they'd prefer a 
way to have 
it accessible from any computer not just one with the key (although 
I'm not sure I think that's the best idea)





Current thread: