views:

295

answers:

7

My application makes use of the RijndaelManaged class to encrypt data. As a part of this encryption, I use a SecureString object loaded with a password which get's get converted to a byte array and loaded into the RajindaelManaged object's Key at runtime.

The question I have is the storage of this SecureString. A user entered password can be entered at run-time, and that can be "securely" loaded into a SecureString object, but if no user entered password is given, then I need to default to something.

So ultimately the quesiton comes down to:

If I have to have some known string or byte array to load into a SecureString object each time my application runs, how do I do that? The "encrypted" data ultimately gets decrypted by another application, so even if no user entered password is specified, I still need the data to be encrypted while it goes from one app to another. This means I can't have the default password be random, because the other app wouldn't be able to properly decrypt it.

One possible solution I'm thinking is to create a dll which only spits out a single passphrase, then I use that passphrase and run it through a couple of different hashing/reorganizing functions at runtime before I ultimately feed it into the secureString object. Would this be secure enough?

Edit For clarity*: The encrypted data is being passed via files between machines. Think of it as a Zip file which always has a password, a default one is assumed if nothing is directly entered by the user.

+7  A: 

There is no point in symmetrically encrypting with a string that's hard-coded into your executable. It will only give a false sense of security. No amount of hashing fixes this scheme.

See this Pidgin FAQ for the same point in a different context.

I am unclear why you think you need the inter-app communication to be encrypted. If this communication is local to the machine, then I don't see the need for encryption, particularly encryption that isn't user-specific. Is this a DRM scheme?

EDIT: If it's being passed to a different machine, perhaps you can hard-code a public key, and then have the other machine decrypt with the matching private key.

Matthew Flaschen
I read the question as coming up with an alternative to hard coding the string in the first place.
Serapth
It is not local to the machine, the encrypted data ends up in xml which is then passed off to a different machine (no direct connection is possible though).
Nick
+1 I totally agree with Pidgin.
Rook
@The Rook: Locks on doors are about as useful as obfuscated passwords. People still lock their doors at night. It may be a false sense of (complete) security, but that's not the same as being insecure. As Lasse V. Karlsen notes, it may be certainly secure enough.
SnOrfus
@SnOrfus the problem that is that encrypting the password doesn't defend against any attack. For the record the pick the pin tumbler lock on your front door in about 30 seconds, so I maybe they aren't so different.
Rook
+2  A: 

This article on securing SQL connection strings should be just as applicable for storing encrypted passwords, where you let the OS handle the encryption of the salting seed for your decryption.

Serapth
+4  A: 

Let me tackle your final question first.

"Would this be secure enough?"

The only one that can answer that is you. Nobody here knows what "secure enough" means in the context of your application.

Are you building an application to keep the diary of teenage girls? Sure, it would be "secure enough".

Are you building an application to encrypt information or authentication for military grade secure systems? Nope, not even close.

You can only rely on one type of security if you intend to store the password in your source code and thus executable, and that is security by obscurity.

If your problem is that you can't, or won't, store the password in the source code, then moving it into a separate dll solves nothing, you've just moved the problem to a different project.

However, I'm wondering about something. You say "I have to default to something". Is that it? You're trying to store a default value for the secure password string in the source code? How about "THISISNOTAPASSWORD"?

Lasse V. Karlsen
Cyber-criminals are far to savvy too be fooled by THISISNOTAPASSWORD. Instead I suggest you employ psychology and go with THISISAPASSWORD.
Serapth
If I this hack issue was assigned to me, I will be really confused with this psychological game. :P
Fraga
+1 for checking to see what 'secure enough' is.
SnOrfus
+2  A: 

It sounds to me like perhaps you should be using a PKI solution instead of encryption/decryption. If you have another application that needs to consume the encrypted data, then you could have a key pair for that application, and give the public key to the app that is doing the encryption. That way you are still keeping your data secure, but not introducing a bunch of additional code that ultimately doesn't give all that much protection.

A quick google search gave me this Code Project article that talks about using the Windows Certificate Store in .Net

ckramer
A: 

There is no secure enough: either it is or it is not.

You might mean is it obscure enough?...

Check the Kerkhoffs Laws

jdehaan
+1  A: 

Eric Lippert's You Want Salt With That? (original blog post)

Also read his post to Use the right tool for the job where he ends with the following tips:

0) If you possibly can, simply don’t go there. Encryption is extremely difficult to get right and is frequently the wrong solution in the first place. Use other techniques to solve your security problems.

1) If the problem is an untrustworthy client then don’t build a security solution which requires trusting the client.

2) If you can use off-the-shelf parts then do so.

3) If you cannot use off-the-shelf-parts and do have to use a cryptosystem then don’t use a cryptosystem that you don’t fully understand.

4) If you have to use a cryptosystem that you don’t fully understand, then at least don’t use it to solve problems it was not designed to solve.

5) If you have to use a cryptosystem to ski through the trees, then at least don’t allow the presumably hostile client to choose the message which is encrypted. Choose the token yourself. If the token must include information from the client then sanitize it in some way; require it to be only straight ASCII text, insert random whitespace, and so on.

6) If you have to allow the client to choose the token, then don’t encrypt the token itself. Sign a cryptographically-secure hash of the token. Its much harder for the attacker to choose a token which produces a desired hash.

7) Don’t use the same key pair for encrypting outgoing messages as you do for protecting incoming messages. Get a key pair for each logically different operation you're going to perform.

8) Encrypt the communications both ways.

9) Consider having a revocation mechanism, so that once you know that Eve is attacking you, you can at least revoke her license. (Or you can revoke a known-to-be compromised license, and so on.)

Robert Paulson
A: 

Have you tried storing it in the machine key?

Read this http://books.google.ca/books?id=ssX3PeW4CTQC&lpg=PP1&dq=Professional%20ASP.NET%203.5&pg=PA1048#v=onepage&q&f=true

It is from the book Professional Asp.net 3.5

chobo2