Fog Creek Software
Discussion Board




ASP and encryption

Hi

I am looking for an encryption algorithm which can be easily implemented in ASP. I've found this:

http://www.4guysfromrolla.com/webtech/010100-1.shtml

What do you recommend? Thanks!

Farid
Tuesday, July 15, 2003

What do I recommend?  As both a security and VBScript expert, let me make this extremely clear:

UNDER NO CIRCUMSTANCES SHOULD YOU EVER IMPLEMENT YOUR OWN ENCRYPTION ALGORITHM.  NEVER NEVER NEVER.

If the data you are protecting is valuable enough to come under attack then:

1) Do a _thorough_ threat modelling analysis of how the data moves around.  Mike Howard's book can help with this.

2) Once you've identified the threats and vulnerabilities, get some crypto experts in to evaluate whether encryption will actually help.  Encryption is not pixie dust that makes things magically secure.  Without actually doing the threat models it is difficult to know whether encryption is an appropriate tool.

3) Once you've determined that encryption is an appropriate mitigating factor to some vulnerability, use the appropriate cryptosystem.  Do not attempt to guess which cryptosystem is suitable for your task -- find a bunch of crypto experts and pay attention to their recommendations.  All cryptosystems are not created equal. 

Believe me, I know how much fun it is to write crypto code.  It is very tempting.  So let me repeat that: DO NOT attempt to roll your own encryption code.  There are approximately one zillion mistakes you can make which can render your cryptosystem about as secure as two cans and a damp string.  Both Windows and the .NET Framework come with professional-grade, high-strength crypto libraries which were implemented by world-class crypto experts and carefully tested by professional crypto testers. 

In case that wasn't sufficiently clear: PARTICULARLY do not attempt to roll crypto code in VBScript -- VBScript is a fun language but it was never designed to do the sorts of hard core bit twiddling and lifetime control required of crypto systems.  It was designed to add 30 line scripts to web pages.

--> Use the right tool for the right job. <-- 

Eric

Eric Lippert
Tuesday, July 15, 2003

Eric, have any funny stories about people implementing their own encryption and how easy it was to break?

Andy
Tuesday, July 15, 2003

Oh yeah, and you want to avoid any of the sketchy algorythms out there, too.  So not only do you need to find an encryption algorythm, but you need to figure out who isn't a scam-artist.

Oh yeah, and anything that isn't part of an existing protocol (PGP/SSL/SSH/Kerberos/etc) is also likely to have hidden problems.  RC4 is a secure encryption algorythm.  When IEEE team 802.11 was designing WEP, they used RC4, but didn't do much to consult with cryptoanalysts and, as a result, made it about as secure as a cardboard wall.

Not to disuade you, but encryption is the sort of thing where there's an order of magnitude more wrong ways to do it than there are right ways... and all of the wrong ways look like great solutions.  If you care about the security, you might want to just contract it out somewhere if you aren't using an existing secure protocol.

Flamebait Sr.
Tuesday, July 15, 2003

Sure, here's one at my expense.

A _very_ frequently requested feature back in the day was "I am selling a script to a third party and if they reverse-engineer it, I want to be able to sue them."

Now, my opinion then was the same as it is now -- if you don't want people mucking with your precious, precious algorithms, don't sell programs to people that implement those algorithms!

Clearly, perfect protection is completely impossible.  This is script, not object code.  Object code can at least in theory be obfuscated somewhat.  (Though I am highly skeptical of the claims of obfuscator vendors.)  But script is, well, script. At some point the plain text has to be given to the interpreter.

So we went back to those people and asked them "suppose we gave you a weak, breakable script encoder that let you put a comment in the code that said 'if you decode this script I'll sue you' ?"

Amazingly, people clamoured for it.  See, legally, you can't hand someone a plaintext and say "don't read this".  But if you can show in court that someone had to hire a hacker to write a decoder utility in direct violation of a licensing agreement, then you have a leg to stand upon, legally.

So, with deep reservations, we implemented a very simple script encoder for VBScript and JScript.

I received an email containing a decoder within two days of its release.  I'm surprised it took that long -- after all, we made the algorithm deliberately weak.  I'm also surprised that it took about two years before it was written up in 2600.

Even implementing an utterly simple, insecure, trivial encoding algorithm, we made mistakes.  For example, there are situations in which scripts encrypted in one locale cannot be decrypted on certain far-east operating systems. 

The funny part was that a few years ago, a third party sent me an email saying that he'd come up with an "unbreakable" script encoding algorithm.  I pointed out to him that he'd have to ship a decoder along with the script engine, otherwise the script compiler couldn't compile the program.  If you ship a decoder, you haven't exactly got "unbreakable" encoding!  The guy got very angry and defensive and never did either show me the program in action or admit that it didn't work.

Eric

Eric Lippert
Tuesday, July 15, 2003

Here's another cautionary tale -- again, at my expense.

When I added support for Software Restriction Policies in Windows Script Host a few years back, of course I used only off-the-shelf crypto technology already built into Windows.  All my custom-built code had to do was to take a script file, extract or embed an opaque signature block, and compute the hash of the script.

That's _all_ it had to do -- all the hard parts, like implementing the hash algorithm, cryptographically verifying the certificate chain, etc, etc, etc, was done for me by cryptoAPI.

Furthermore, I had the benefit of having the guys who architected and implemented Software Restriction Policies right there with me, helping me out.

Sounds easy, right?  Just pass the script text to the cryptoAPI's function that computes a SHA1 hash, bag off work and go sailing, right?

Not so fast.  Consider two signed scripts with identical text -- one on disk in UTF8, one on disk in UTF16.  Those should both hash to the same value.  What if one begins with a Unicode Byte Order Mark and the other doesn't?  There are a tonne of canonicalization issues here! 

So I wrote a whole bunch of code to convert the script into a canonical UTF-16 memory image and hashed the image rather than the file.

So that's it, right?  Puget Sound, here I come.

Not so fast -- obviously the signature block cannot be included in the hash, because the signature block CONTAINS the hash.  So I wrote some code to detect when the script contained a signature block, removed it in memory, and hashed the new result.

And then I was done, and down at Shilshole Bay putting on a wetsuit, right?

Not so fast!  :-) 

Do you see what was missing?  At first I didn't either, but fortunately I noticed the problem a few days later -- before we shipped the final bits to customers. 

The code which extracted the signature block extracted the signature block from ANYWHERE in the script.  That means that a signed script with the signature block embedded at the END had the same hash as the same script with the block embedded in the MIDDLE -- but for .WSF files, the runtime won't compile a script with a signature block in the middle! 

That meant that it was possible to have a legal, signed, "guaranteed to be unmodified" script that wouldn't run at all.

Whoops. 

So I fixed it. The hash algorithm now adds on the position at which the signature block is to be embedded as part of the hash.  If it's not still there when the hash is verified, well, that hash won't verify.

********************

I could give many more examples, but you take my point.  Getting all the details right is insanely difficult, even when you have amazing resources at your disposal, and getting any detail wrong can render the entire effort pointless.

Eric

Eric Lippert
Tuesday, July 15, 2003

Eric, they've pretty much mathematically proven that all forms of code obfustication (even for object code) can be broken.

Flamebait Sr.
Tuesday, July 15, 2003

Yeah, I recommend against people using obfuscators.  To defeat a given obfuscation scheme, how many times do the attackers have to write a deobfuscator?  Once!  And how many attackers are there out there willing to try?  Lots!  That strikes me as a losing proposition for the obfuscator manufacturers.

Eric

Eric Lippert
Tuesday, July 15, 2003

OK. But to answer the original question. You could wrap the crypt++ libraries in a COM control and use that.

Joel Spolsky
Tuesday, July 15, 2003

ASPEncrypt is a package from Persit's you might consider. It's an ASP Component written I guess in C++ designed to handle most of what you need. Last I used it the only thing missing was a function that returned pseudo randoms.

That can be had by writing a VB-based asp component accessing CryptoAPI's CryptGenRandom. (If someone wrote this for free let me know!)

There's really no reason to implement your own.

I have seen some people try to do a good RC4 or SHA1 hash in javascript for client-side password encryption for challenging users with the proper secret to protect web accounts without SSL enabled. But that's just a poor workaround that could give you a false sense of security.

Li-fan Chen
Tuesday, July 15, 2003

If someone knows of a Crypt++ Com wrapper (for free or fee) please let me know.

Li-fan Chen
Tuesday, July 15, 2003

Thanks to the ease of .Net Framework's Interp.. you might actually invest the time to learn the .Net libraries for encryption. Then expose it in a COM like manner and register them as COM classes. Your ASP (and VB) should be able to access this. Both ASPEncrypt and .Net's encryption are wrappers around Microsoft's CryptoAPI I think. Please correct me if I am wrong.

Li-fan Chen
Tuesday, July 15, 2003

Peter Gutmann's cryptlib is a very high quality crypto library which provides an extensive set of functions, and includes an Active X wrapper. It is available from:

http://www.cs.auckland.ac.nz/~pgut001/cryptlib/

The library is issued under a dual license - free for private/educational use, but with a fee (I believe fairly modest) for commercial use.

ajs
Tuesday, July 15, 2003

OK, but let me emphasize again to not have the solution chase the problem. 

First do a thorough threat analysis to see if encryption is necessary -- encryption does not stop XSS vulnerabilities, for example.  Second, determine what crypto algorithms are appropriate.  THEN, and only then does it make any sense to start talking about what libraries do what you want. 

Once you get to that point, I'd start by looking at CryptoAPI if you're calling from unmanaged code, CAPICOM.DLL if you're calling from script and the Cryptography namespaces if you're calling from managed code.

Eric

Eric Lippert
Wednesday, July 16, 2003

Should I do a thread analysis examination first before deciding if I should store plaintext user passwords in my database?

FredSavage
Wednesday, July 16, 2003

Well, it depends on how irked you think those users would be if you let attackers have all their plaintext passwords.  If the answer is not "they'd be thrilled!" then I personally would want to do a threat model...  :-)

Eric Lippert
Wednesday, July 16, 2003

Fred-
Yes you need to understand the threats. If your database is running on an unusual system sitting inside a sealed box in a locked room, and talks over some sort of encryped channel to the outside and returns a 'yes' or 'no' for 'is this user X' password in a constant amount of time, then you don't need to encrypt the user's password.

Of course you might want encrypt the password, but if someone can steal your list of encrypted passwords they can just spend time attacking the password on their own machines.

In reality you probably need some of each.

mb
Wednesday, July 16, 2003

...then you don't need to encrypt the user's password *in the database*.

mb
Wednesday, July 16, 2003

*  Recent Topics

*  Fog Creek Home