1

I need to store "password like information" in a database field. I would like it to be encrypted but I need to decrypt it before using it. So I can not use a Hash/Salt solution.
Granted if an attacker made it that far into the database it may be too far gone but I figure this would at least stop the mistaken dump of the data.

  1. How to encrypt a value store it into the database and decrypt the same value for use later?

  2. Hashing is not an option (I use it on other parts actually).

  3. Where to store the private key? Users would not supply anything.

This a C# solution so .NET specific stuff would be great. My question is very similar but I am looking for a .net based solution: Two-way encryption: I need to store passwords that can be retrieved

EDIT: Hogan pretty much answered my question. I found examples out there and they ranged from very complicated to rather simple. It looks like AES is still good so I will be using that method. thank you for all your help.

Community
  • 1
  • 1
Dan
  • 741
  • 1
  • 10
  • 22
  • 1
    do a google search on how to encrypt passwords in SQL Server using `SHA1` once you get that setup you can easily write your own encrypt / decrypt code on the .net end.. I've done this before and even if you don't use SQL Servers encryption you can still write your own code do some google searching as I have stated earlier – MethodMan Sep 17 '15 at 20:12
  • @MethodMan are you trolling? -- sha1 is a hash function. – Hogan Sep 17 '15 at 20:13
  • have you considered using AD? – tdbeckett Sep 17 '15 at 20:14
  • Dan I'm not sure I understand, there many 2 way encryption functions supported in .net and plenty of examples available -- is there something specific about your problem that isn't solved with a standard solutions? As it is worded your question is way to general and sounds like you are asking for a recomendation – Hogan Sep 17 '15 at 20:14
  • I see some very complicated solutions like: http://stackoverflow.com/questions/202011/encrypt-and-decrypt-a-string/10366194#10366194 and then I see some rather simple solutions http://www.codeproject.com/Tips/839656/How-to-encrypt-and-decrypt-string-using-AES-algori What am I missing because the simple solution seems so easy. – Dan Sep 17 '15 at 20:19
  • I don't know that there is any way to do it without knowing the salt/key that you used to encrypt it. In the past, we have used the database key, which is of course different for every row, to encrypt data in the record. it's not that great, but it's a step up. One thing with this approach, if you start moving data around, you have to really certain you don't change keys. – CargoMeister Sep 17 '15 at 20:22
  • Both of those solutions are fine -- they are exactly what I mean when I said "plenty of examples available" And yes... the simple solution is fine. You still have to decide how to protect the key. – Hogan Sep 17 '15 at 20:29
  • CargoMeister I would have the keys to decrypt/encrypt stored somewhere. Basically I have to store logon information for outside systems so that stuff can be run automated. – Dan Sep 17 '15 at 20:29
  • Can you define "password like information"? Passwords never need to be (nor should they be) decrypted, so they can use a one-way algorithm. There are a lot of public/private key encryption systems like RSA, the question is where you store the keys... – Ron Beyer Sep 17 '15 at 20:37
  • It is an automated system that uses secret keys to communicate with other systems. In theory with this information can be use by an unauthorized system if the real value plain text value was recovered. – Dan Sep 17 '15 at 20:42

1 Answers1

1

One solution that does not involve private keys is using DPAPI.

You can use it from .NET via the ProtectedData class.

Here is an example:

public void Test()
{
    var password = "somepassword";

    var encrypted_password = EncryptPassword(password);

    var decrypted_password = DecryptPassword(encrypted_password);
}

public string EncryptPassword(string password)
{
    var data = Encoding.UTF8.GetBytes(password);

    var encrypted_data = ProtectedData.Protect(data, null, DataProtectionScope.CurrentUser);

    return Convert.ToBase64String(encrypted_data);
}

public string DecryptPassword(string encrypted_password)
{
    var encrypted_data = Convert.FromBase64String(encrypted_password);

    var data = ProtectedData.Unprotect(encrypted_data, null, DataProtectionScope.CurrentUser);

    return Encoding.UTF8.GetString(data);
}

Please note that DPAPI in this case depends on the current logged in user account. If you encrypt the password when your application is running as User1, then you can only decrypt the password running under the same user account. Please note that if you change the windows password for User1 in an incorrect way, then you will lose the ability to decrypt the password. See this question for details.

If you don't want use DPAPI, and prefer to have a private key. Then the best place to store such private key is in the user's key store. However, in order to store a private key in the local user store, you need to have a certificate for it. You can create a self signed certificate and store it with its corresponding private key into the local user certificate store.

You can access the user store in code using the X509Store class. You can use it to find the certificate (which is in C# a X509Certificate2 class) that you want to use and then use it to do encryption/decryption.

See this and this for more details.

Community
  • 1
  • 1
Yacoub Massad
  • 27,509
  • 2
  • 36
  • 62
  • This solution is only compatible for the Windows platform. The compiler complains with a code [CA1416](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1416). I can't seem to find a solution that works on every platform. – badjuice Feb 23 '22 at 16:24