¿Cómo puedo cifrar la configuración del usuario (tales como contraseñas) en mi aplicación?

Quiero para proporcionar al usuario la posibilidad de guardar datos personales cifrados. Este podría ser trivial, o puede haber sido preguntado ya, pero no soy capaz de encontrar un ejemplo de un fácil de usar para cifrar/descifrar una contraseña.

Yo realmente no necesita ningún super-magia-irrompible contraseña. Solo me falta la contraseña para ser como difícil de romper.

He visto algunos de msdn y LO preguntas, pero no he encontrado algo que pueda usar.

  • Relacionadas con la pregunta: Cómo cifrar una contraseña para guardar más tarde en una base de datos o un archivo de texto?. Y mucho, mucho más: las Preguntas que contengan ‘c# cifrar la contraseña’.
  • Tenga en cuenta que cualquier cosa que hagas, que no descifrar contraseñas. Más bien, se asegura de que los dos hashes partido.
  • es allí una manera de enviar el hash de la contraseña en la cadena de conexión sql?
  • No sé nada acerca de SQL, pero estoy seguro que no debe ser. Un hash de la contraseña sería exactamente igual que cualquier otro texto o valor numérico.
  • Usted no desea utilizar las contraseñas de los usuarios en las cadenas de conexión. Suponiendo que usted está en SQL Server, haciendo que impide que las conexiones de ser común, y así disminuye el rendimiento. En lugar de ello, tienen una cuenta de la que se conecta a SQL Server mediante la autenticación de Windows.
InformationsquelleAutor Odys | 2012-01-15

3 Kommentare

  1. 33

    David, Pensé su respuesta fue ingeniosa, pero pensé que esos serían niftier como los métodos de extensión. Que permitan dicha sintaxis como:

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

    Aquí está el código actualizado:

    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);
            }
        }
    }
    • Buena mejora. He copiado el código de un viejo proyecto de prueba de unidad donde yo estaba en la utilización real de las cuentas de usuario y contraseñas para la prueba. Quería guardar las contraseñas de forma segura para que yo pudiera ejecutar las pruebas sin tener que abrir o registrar contraseñas en texto plano.
    • Véase la nota I de la izquierda de abajo de @DavidClarke ‘s respuesta, y ver este msdn enlace
  2. 17

    La siguiente es tan simple como se pone, suponiendo que realmente sólo quiero ser capaz de cifrar/descifrar una cadena y almacenar en el disco. Nota esto no utilice una contraseña, utiliza el contexto de seguridad del usuario que ha iniciado sesión Sistema.De seguridad.La criptografía.DataProtectionScope.CurrentUser para asegurar los datos.

    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;
        }
    
    }

    Luego cifrar una cadena:

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

    Y, posteriormente, descifrar:

    var clearText = SecureIt.ToInsecureString( SecureIt.DecryptString(cypherText));
    • Si usted descifrar una cadena segura no hay un punto en el uso de una cadena segura. El propósito es mantener la cadena completa de un solo bloque de memoria. Usted no es mejor usar este método de lo que sería si usted acaba de tomar una cuerda y la cifró: A SecureString object should never be constructed from a String, because the sensitive data is already subject to the memory persistence consequences of the immutable String class. The best way to construct a SecureString object is from a character-at-a-time unmanaged source, such as the Console.ReadKey method.
    • Ese es un buen punto. No estoy sugiriendo que todos los métodos deben ser utilizados en la misma aplicación. Yo estaba usando una consola independiente de la aplicación para la captura de la cadena y cifrar antes de guardarla de forma segura en la configuración de un proyecto de prueba de unidad. La intención es proporcionar la suficiente seguridad para el contexto en el que se estaba utilizando.
  3. 1

    Para mi propósito modificar Jesse C. Segmentación De Datos solución para no utilizar SecureString como no es importante para mí para proteger la memoria. Sólo necesito para serializar cadenas cifradas. Para hacer este trabajo del proyecto debe tener una referencia a la System.Security (no sólo la instrucción de uso).

    public static class StringSecurityHelper
    {
        private static readonly byte[] entropy = Encoding.Unicode.GetBytes("5ID'&mc %[email protected]%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;
            }
        }
    }

    Y a utilizar:

    string cypherText = "My string".EncryptString();
    string clearText = cypherText.DecryptString();

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea