Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I encrypt user settings (such as passwords) in my application?

Tags:

c#

.net

winforms

I want to provide the user the ability to save personal data encrypted. This might be trivial or might have been already asked, but I am not able to find an example of an easy to use way to encrypt/decrypt a password.

I really don't need any super-magic-unbreakable password. I just need the password to be like difficult to break.

I've seen some MSDN and SO questions but haven't found something to use.

like image 921
Odys Avatar asked Jan 15 '12 16:01

Odys


People also ask

How do I encrypt my username and password?

If you send the encryption key from the server to the client or the other way around you need to encrypt your symmetric encryption key. The easiest way to do this would be to use TLS. If you use TLS, then the data as well as key are encrypted, so you don't need to encrypt it yourself.

What encryption should I use for passwords?

Advanced Encryption Standard (AES) At 128 bits, AES is sufficiently secure, but most organizations prefer heavy-duty 256-bit encryption. At TeamPassword, we use 256-bit encryption to store passwords, ensuring the highest levels of security for our clients.

How does encryption work with passwords?

Encryption scrambles your password so it's unreadable and/or unusable by hackers. That simple step protects your password while it's sitting in a server, and it offers more protection as your password zooms across the internet. Imagine that you've created the strongest password possible.


3 Answers

David, I thought your answer was nifty, but I thought those would be niftier as extension methods. That would allow such syntax as:

string cypherText;
string clearText;

using (var secureString = "Some string to encrypt".ToSecureString())
{
    cypherText = secureString.EncryptString();
}

using (var secureString = cypherText.DecryptString())
{
    clearText = secureString.ToInsecureString();
}

Here's the updated code:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Text;

public static class SecureIt
{
    private static readonly byte[] entropy = Encoding.Unicode.GetBytes("Salt Is Not A Password");

    public static string EncryptString(this SecureString input)
    {
        if (input == null)
        {
            return null;
        }

        var encryptedData = ProtectedData.Protect(
            Encoding.Unicode.GetBytes(input.ToInsecureString()),
            entropy,
            DataProtectionScope.CurrentUser);

        return Convert.ToBase64String(encryptedData);
    }

    public static SecureString DecryptString(this string encryptedData)
    {
        if (encryptedData == null)
        {
            return null;
        }

        try
        {
            var decryptedData = ProtectedData.Unprotect(
                Convert.FromBase64String(encryptedData),
                entropy,
                DataProtectionScope.CurrentUser);

            return Encoding.Unicode.GetString(decryptedData).ToSecureString();
        }
        catch
        {
            return new SecureString();
        }
    }

    public static SecureString ToSecureString(this IEnumerable<char> input)
    {
        if (input == null)
        {
            return null;
        }

        var secure = new SecureString();

        foreach (var c in input)
        {
            secure.AppendChar(c);
        }

        secure.MakeReadOnly();
        return secure;
    }

    public static string ToInsecureString(this SecureString input)
    {
        if (input == null)
        {
            return null;
        }

        var ptr = Marshal.SecureStringToBSTR(input);

        try
        {
            return Marshal.PtrToStringBSTR(ptr);
        }
        finally
        {
            Marshal.ZeroFreeBSTR(ptr);
        }
    }
}
like image 148
Jesse C. Slicer Avatar answered Oct 23 '22 20:10

Jesse C. Slicer


The following is about as simple as it gets, assuming you really just want to be able to encrypt/decrypt a string and store it to disk. Note this doesn't use a password, it uses the security context of the logged in user System.Security.Cryptography.DataProtectionScope.CurrentUser to secure the data.

public class SecureIt
{
    static byte[] entropy = System.Text.Encoding.Unicode.GetBytes("Salt Is Not A Password");

    public static string EncryptString(System.Security.SecureString input)
    {
        byte[] encryptedData = System.Security.Cryptography.ProtectedData.Protect(
            System.Text.Encoding.Unicode.GetBytes(ToInsecureString(input)),
            entropy,
            System.Security.Cryptography.DataProtectionScope.CurrentUser);
        return Convert.ToBase64String(encryptedData);
    }

    public static SecureString DecryptString(string encryptedData)
    {
        try
        {
            byte[] decryptedData = System.Security.Cryptography.ProtectedData.Unprotect(
                Convert.FromBase64String(encryptedData),
                entropy,
                System.Security.Cryptography.DataProtectionScope.CurrentUser);
            return ToSecureString(System.Text.Encoding.Unicode.GetString(decryptedData));
        }
        catch
        {
            return new SecureString();
        }
    }

    public static SecureString ToSecureString(string input)
    {
        SecureString secure = new SecureString();
        foreach (char c in input)
        {
            secure.AppendChar(c);
        }
        secure.MakeReadOnly();
        return secure;
    }

    public static string ToInsecureString(SecureString input)
    {
        string returnValue = string.Empty;
        IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(input);
        try
        {
            returnValue = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(ptr);
        }
        finally
        {
            System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr);
        }
        return returnValue;
    }

}

Then to encrypt a string:

  var clearText = "Some string to encrypt";
  var cypherText = SecureIt.EncryptString( SecureIt.ToSecureString( clearText));

And to subsequently decrypt:

var clearText = SecureIt.ToInsecureString( SecureIt.DecryptString(cypherText));
like image 19
David Clarke Avatar answered Oct 23 '22 18:10

David Clarke


For my purpose I modify Jesse C. Slicer solution to not use SecureString as it's not important for me to protect memory. I just need to serialize encrypted strings. To make this work project need to have reference to System.Security (not only using statement).

public static class StringSecurityHelper
{
    private static readonly byte[] entropy = Encoding.Unicode.GetBytes("5ID'&mc %sJo@lGtbi%n!G^ fiVn8 *tNh3eB %rDaVijn!.c b");

    public static string EncryptString(this string input)
    {
        if (input == null)
        {
            return null;
        }

        byte[] encryptedData = ProtectedData.Protect(Encoding.Unicode.GetBytes(input), entropy, DataProtectionScope.CurrentUser);

        return Convert.ToBase64String(encryptedData);
    }

    public static string DecryptString(this string encryptedData)
    {
        if (encryptedData == null)
        {
            return null;
        }

        try
        {
            byte[] decryptedData = ProtectedData.Unprotect(Convert.FromBase64String(encryptedData), entropy, DataProtectionScope.CurrentUser);

            return Encoding.Unicode.GetString(decryptedData);
        }
        catch
        {
            return null;
        }
    }
}

And to use it:

string cypherText = "My string".EncryptString();
string clearText = cypherText.DecryptString();
like image 2
Logman Avatar answered Oct 23 '22 18:10

Logman