Symmetric encryption keys

M

Mark Rae

Hi,

Picking your collective brains again, this time regarding the storage of the
key used in symmetric encryption.

Let's say you have a requirement to add encryption to a C# project, so you
might choose the TripleDESCryptoServiceProvider class:
http://msdn2.microsoft.com/en-us/li...ptography.tripledescryptoserviceprovider.aspx

No worries - it doesn't present much of a challenge, the MSDN code samples
are easy enough to follow - we're probably looking at a matter of minutes to
knock up an Encryption class with an Ecrypt() and a Decrypt() method.

The text states "This algorithm supports key lengths from 128 bits to 192
bits in increments of 64 bits". Again, not a problem - you need a key to
encrypt the data, and you need the same key to decrypt it again - the
encrypted data can't be (easily) decrypted without the key which was used to
encrypt it in the first place.

Obviously, you're adding encryption to your project as some sort of a
security measure, so you'd imagine that you'd make the key as difficult to
find as possible. But, your app itself needs to know the key, or nothing
works... :)

Given the premise that ultimately *anything* is hackable, and .NET
assemblies can be disassembled even if obfuscated, where would you typically
store the actual key itself so that your app can use it but hackers will
struggle to find it...?

1) hard-code it into the C# code so that it gets compiled along with the
rest of the code?

2) store it in your app's config file?

3) store it in a resource file?

4) some other storage mechanism?

And, finally, would you use the same storage mechanism for a WinForms app as
for a WebForms app?

Any assistance gratefully received, as always...

Mark
 
S

Stephany Young

This one is almost a 'how long is a piece of string' question. You will get
as many different answers as there are responders and all of them will be
valid.

But ... here's what we did for a 'closed' environment where we wanted to
store some sensitive values in a config file but 'hide' them from prying
eyes.

1. Get the sensitive value into an array of bytes.

2. Base64 encode the array into a string.

3. Reverse the string.

4. Base64 encode it again.

5. Strip any trailing = characters.

6. Store the result any where you like.

To 'decode' the value:

1. Retrieve the 'encoded' value.

2. Pad it with trailing = characters until the length is a multiple of 4.

3. Base64 decode it.

4. Reverse the string.

5. Base64 decode it again.

6. Put the string into a byte array,

Certainly a cryptologist would 'crack' it in nothing flat and a 'hacker'
would probably be able to find your encode/decode methods but the risk of a
normal user being able to 'crack' it would be negligible.

In my view it doesn't really matter how one does it, it's more important to
find a methodology that reduces the 'risk' to an acceptable level.
 
M

Mark Rae

This one is almost a 'how long is a piece of string' question. You will
get as many different answers as there are responders and all of them will
be valid.

That's fine - no problem with that...
But ... here's what we did for a 'closed' environment where we wanted to
store some sensitive values in a config file but 'hide' them from prying
eyes.

<snip>

Well, that seems reasonable enough...
Certainly a cryptologist would 'crack' it in nothing flat and a 'hacker'
would probably be able to find your encode/decode methods but the risk of
a normal user being able to 'crack' it would be negligible.

That is understood.
In my view it doesn't really matter how one does it, it's more important
to find a methodology that reduces the 'risk' to an acceptable level.

Exactly what I'm hoping to achieve - thanks for the response.
 
R

rossum

Hi,

Picking your collective brains again, this time regarding the storage of the
key used in symmetric encryption.

Let's say you have a requirement to add encryption to a C# project, so you
might choose the TripleDESCryptoServiceProvider class:
http://msdn2.microsoft.com/en-us/li...ptography.tripledescryptoserviceprovider.aspx

No worries - it doesn't present much of a challenge, the MSDN code samples
are easy enough to follow - we're probably looking at a matter of minutes to
knock up an Encryption class with an Ecrypt() and a Decrypt() method.

The text states "This algorithm supports key lengths from 128 bits to 192
bits in increments of 64 bits". Again, not a problem - you need a key to
encrypt the data, and you need the same key to decrypt it again - the
encrypted data can't be (easily) decrypted without the key which was used to
encrypt it in the first place.

Obviously, you're adding encryption to your project as some sort of a
security measure, so you'd imagine that you'd make the key as difficult to
find as possible. But, your app itself needs to know the key, or nothing
works... :)

Given the premise that ultimately *anything* is hackable, and .NET
assemblies can be disassembled even if obfuscated, where would you typically
store the actual key itself so that your app can use it but hackers will
struggle to find it...?

1) hard-code it into the C# code so that it gets compiled along with the
rest of the code?

2) store it in your app's config file?

3) store it in a resource file?

4) some other storage mechanism?

And, finally, would you use the same storage mechanism for a WinForms app as
for a WebForms app?

Any assistance gratefully received, as always...

Mark
You might get some good advice on sci.crypt, where this sort of thing
is common.

You need to decide who you are protecting your key from: Aunt Edna,
Nasty Megacorp Inc. or government agencies with three letter names.
The degree of protection you want will depend on who you are
protecting against.

Base64 is enough to protect from Aunt Edna. For Nasty Megacorp you
will need something more sophisticated. Best not to keep the key in
the source file, keep something on a file elsewhere (even on a memory
stick in a locked safe if practical). The key itself should not be
stored, instead store the information needed to calculate the key. A
usual method is to take a user-entered passphrase, add some
cryptographic salt and hash the result (SHA-256 or similar) to give
the actual key. You could store the passphrase and salt in separate
files, with or without some light encryption, if you did not want the
users to have to actually enter anything.

rossum
 
M

Mark Rae

You might get some good advice on sci.crypt, where this sort of thing
is common.

Thanks - I'll take a look.
You need to decide who you are protecting your key from: Aunt Edna,
Nasty Megacorp Inc. or government agencies with three letter names.
The degree of protection you want will depend on who you are
protecting against.

Somewhere in the middle of those three. The vast majority of my clients
aren't really computer-savvy, so that forms only a small part of my reason
for doing this. I'm mostly doing it as a CYA measure so that I can include
in documentation that I've made "reasonable" efforts to protection the
encryption - due diligence, and all that.

Obviously, nothing is completely uncrackable... :)
Base64 is enough to protect from Aunt Edna. For Nasty Megacorp you
will need something more sophisticated. Best not to keep the key in
the source file, keep something on a file elsewhere (even on a memory
stick in a locked safe if practical). The key itself should not be
stored, instead store the information needed to calculate the key. A
usual method is to take a user-entered passphrase, add some
cryptographic salt and hash the result (SHA-256 or similar) to give
the actual key. You could store the passphrase and salt in separate
files, with or without some light encryption, if you did not want the
users to have to actually enter anything.

I'm reasonably familiar with the encryption process, so was mainly looking
for some "best practice" advice - I think your paragraph above is the
approach I'm heading for...

Thanks.
 
R

rossum

Thanks - I'll take a look.


Somewhere in the middle of those three. The vast majority of my clients
aren't really computer-savvy, so that forms only a small part of my reason
for doing this. I'm mostly doing it as a CYA measure so that I can include
in documentation that I've made "reasonable" efforts to protection the
encryption - due diligence, and all that.

Obviously, nothing is completely uncrackable... :)


I'm reasonably familiar with the encryption process, so was mainly looking
for some "best practice" advice - I think your paragraph above is the
approach I'm heading for...

Thanks.
For best practice you may find some RFCs of use. If you are using
Triple DES have a look at RFC 3271:
(ftp://ftp.rfc-editor.org/in-notes/rfc3217.txt) on key wrapping.
Unless you need to for reasons of backwards compatibility I would
suggest using AES (Rijndael in .NET) instead. For AES key wrapping
see RFC 3394 (ftp://ftp.rfc-editor.org/in-notes/rfc3394.txt).

Other relavant RFCs include RFC 3537, RFC 3562 and RFC 4107.

rossum
 
M

Mark Rae

For best practice you may find some RFCs of use. If you are using
Triple DES have a look at RFC 3271:
(ftp://ftp.rfc-editor.org/in-notes/rfc3217.txt) on key wrapping.
Unless you need to for reasons of backwards compatibility I would
suggest using AES (Rijndael in .NET) instead. For AES key wrapping
see RFC 3394 (ftp://ftp.rfc-editor.org/in-notes/rfc3394.txt).

Other relavant RFCs include RFC 3537, RFC 3562 and RFC 4107.

Thanks once again.
 

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