Re: How to convert a SecureString into an encrypted String in a se
- From: "Joe Kaplan" <joseph.e.kaplan@xxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Fri, 31 Aug 2007 09:35:54 -0500
The way you were using the interop marshaling classes to get the data out of
secure string and into a byte array looked a little weird to me, but I
haven't played with SecureString that much and wasn't prepared to comment on
it. Looking at it more now, it seems like it is probably fine. You need to
use SecureStringtoBSTR to get the data out and that gives you an IntPtr.
You can then either convert that to a .NET string (not a good idea if the
point was to use a SecureString in the first place) or read the memory into
your CryptoStream via some mechanism. Walking the pointer seems reasonable
as a way to do that, so basically that code looks fine to me. :)
I think your alg and key length is fine. If you feel that you can securely
store that key, then that is fine too. Note that the weakness in your
system probably ends up reducing to how well you are able to secure that
key. If you wanted to make things more secure, you might consider rotating
keys periodically and re-encrypting your values.
Now, on to the IV. You should always use a new, random IV when encrypting
any data with a symmetric alg that uses CBC (which Rjindael does by
default). Using a null IV is bad crypto hygeine, as is using a single fixed
IV for all transformations. The IV is NOT a secret, but it does need to be
different every time.
What you probably want to do is something like this:
Generate new IV via RNG function
Encrypt data using fixed key, new random IV and plaintext binary data
Create a new byte array containing the IV + cipher text (prepend IV probably
easiest)
Convert the entire thing to base64
Save in database
To reverse, you just need to make sure you separate the IV from the cipher
text after you convert from base64 to binary. Since IV is fixed length,
this is easy to do with some array manipulation.
You can also store the IV in a separate column in the database if you like,
but combining the data allows you to keep your current db schema.
So, basically I think you are pretty close to being good here. If you
implement the IV suggestion and store the key securely (whatever that means
:)), this should be pretty hard to compromise.
Note that you can encrypt your SQL network traffic on the wire if you are
using Windows auth by using SSPI encryption.
Joe K.
--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--
"Michael Brandt Lassen" <MichaelBrandtLassen@xxxxxxxxxxxxxxxxxxxxxxxxx>
wrote in message news:E39AB4B6-E5ED-4FFF-A5A6-A4EA7209E52D@xxxxxxxxxxxxxxxx
Hey Joe.
Thank you so much for your answer.
First, let me shine some light on the "threat model" of this application:
The app is running on our internal network, which means inside our
firewall.
It's an ASP.NET 2.0 web app, running on IIS 6.0 with Integrated Windows
Authentication, so only authorised active directory users can access it.
The
app is also using Forms Authentication to authenticate the user against
the
RACF-backend. It's this authentication against RACF that we wish to
automate
using stored passwords.
Now, about the chosen encryption: Before reading your answer, we were
planning to encrypt the passwords using the symmetric Rijndael algorithm,
with a single 256 bit key for all users.
We also planed to hide the key and initialisation vector (IV) in an
encrypted section of the applications configuration file (web.config),
along
the lines of the article: "How To: Encrypt Configuration Sections in
ASP.NET
2.0 Using DPAPI" (http://msdn2.microsoft.com/en-us/library/ms998280.aspx).
Finally, we planed to protect the configuration file itself using NTLM.
With our thread model, should we go for a key per user? How should we
obtain
these, and where should they be stored?
I'm no sure if I fully understand the issues around a random IV. How do
your
suggest we achieve a real random IV?
I've already looked into SQL Server 2005 encryption, but I didn't like the
fact that I had to pass the password unencrypted from the data access
layer
to the database. Should I do both, that is encrypt the passwords in the
business layer and encrypt it once again in SQL Server 2005?
And by the way, I'd still like comments on the very conversion from
SecureString to encrypted string.
I just go one crazy idea: What if we generate a key for each user based on
the very password of the user (that is an unencrypted string version)
using
the Rfc2898DeriveBytes class, between sessions we could store the key in
the
user specific isolated storage. Sure this leads to some web-farm issues.
Best regards,
Michael Brandt Lassen
.
- References:
- Prev by Date: Re: I want to read a .pfx and use the private key to sign a document, is that "that" bad?
- Next by Date: My Programmers want me to have run this CALL command
- Previous by thread: Re: How to convert a SecureString into an encrypted String in a secure manner?
- Next by thread: Re: SSH2 RSA key import/export
- Index(es):
Relevant Pages
|