c# - infosolutions - ¿Cómo encriptar una contraseña para guardarla más tarde en una base de datos o archivo de texto?
login encriptado c# (14)
¿Necesitas encriptarlo otra vez? de lo contrario, utilice una función de hash para encriptarlo y cifrar la contraseña dada por el usuario con la misma función de hash y ver si los hash son iguales.
La razón por la que no se utiliza un cifrado bidireccional es que no se puede descifrar la clave, ya que una buena función tiene colisiones.
Quiero que mi aplicación guarde la contraseña encriptada en una base de datos o en un archivo de texto. ¿Cómo puedo hacer eso suponiendo que alguien puede abrir la base de datos o el archivo de texto?
Duplicar
Encriptación / hash de contraseñas de texto sin formato en la base de datos
No duplicado , estoy pidiendo un código específico para .NET
EDITAR: estoy guardando la contraseña para un uso posterior. Necesito decodificarlo y usarlo para iniciar sesión. No tiene que ser súper seguro, solo debe ser ilegible para el ojo humano y difícil de decodificar con un guión trivial.
¿Realmente necesita poder recuperar la contraseña? Si está almacenando una contraseña con el propósito de autenticar a alguien (o algo), debería usar hash (con salazón) y luego comparar ese hash con el hash de la contraseña proporcionada por la parte que desea autenticarse.
Si, por otro lado, necesita almacenar la contraseña para poder recuperarla y suministrarla a algún otro servicio de autenticación más adelante, entonces puede guardarla encriptada. En ese caso, use cualquier algoritmo de cifrado simétrico decente que pueda, como TripleDES o AES o Blowfish.
Brevemente:
Obtenga un gran número aleatorio que mantendrá en privado y solo tendrá acceso al código de su aplicación.
Encripte la contraseña + número aleatorio con un algoritmo de ancryption como SHA1, la mayoría de los lenguajes de programación tienen un marco de criptografía.
Almacene la contraseña hash.
Más tarde, cuando desee verificar las contraseñas introducidas, puede reajustar las entradas del usuario y compararlas con las contraseñas almacenadas "virtualmente" e indescifrables.
Como ocdecio usaría TripleDes, también guardaría la sal en la base de datos. La clave para mí suele estar codificada, pero la sal debe cambiar para cada elemento encriptado.
Si solo necesita la contraseña para un proceso de autenticación interno, no debe guardar la contraseña real, sino guardar un hash de esta contraseña. Cuando necesite verificar si una contraseña es válida, deberá ejecutar la función hash en la contraseña proporcionada y compararla con el hash que almacenó en su base de datos / archivo. Nunca puede encontrar la contraseña original del hash.
Si necesita conservar la contraseña original, deberá encriptarla. Puede utilizar, por ejemplo, una infraestructura de clave pública si tiene un proceso que escribe las contraseñas (clave pública) y otra que las lee (clave privada).
Si usa el cifrado para almacenar contraseñas de forma segura, también deberá almacenar la "clave" de cifrado en algún lugar. Este será el "enlace débil", ya que si alguien se apodera de la clave de cifrado, podrá descifrar las contraseñas encriptadas.
Como se trata de contraseñas de las que estamos hablando aquí, una solución mucho mejor es usar un hash de un solo sentido. Hash la contraseña cuando el usuario la crea por primera vez (preferiblemente hash con un valor de sal) y almacena el valor hash resultante. Dado que los hash son unidireccionales, nadie puede revertir el hash al valor original de texto sin formato.
Para comprobar que la contraseña de un usuario es correcta, simplemente solicite al usuario la contraseña de texto sin formato, vuelva a ingresar su hash y compare el valor hash resultante con el valor hash que ha almacenado (tomando en cuenta las sales, por supuesto). Si los dos valores de hash son iguales, el usuario ha ingresado la contraseña correcta.
Por favor, consulte los siguientes enlaces para obtener más información: Contraseña Hashing con sal
Para el cifrado (si necesita usar eso), usaría Rijndael (AES) .
BCrypt - Fuerte hashing de contraseña para .NET y Mono
Los lectores de no saben cómo escribir esquemas de contraseñas seguros y usted tampoco. Si va a hacer eso, ahorre tiempo al quedarse con el texto simple. De suficiente con las tablas del arco iris: Lo que necesita saber sobre los esquemas de contraseña segura :
Las tablas Rainbow son fáciles de superar. Para cada contraseña, genere un número aleatorio (un nonce). Hash la contraseña con el nonce, y almacena el hash y el nonce. El servidor tiene suficiente información para verificar las contraseñas (el nonce está almacenado en forma clara). Pero incluso con un pequeño valor aleatorio, digamos, 16 bits, las tablas del arcoíris son inviables: ahora hay 65,536 "variantes" de cada hash, y en lugar de 300 mil millones de entradas de la tabla del arco iris, se necesitan cuatrillones. El nonce en este esquema se llama una "sal".
Genial, ¿eh? Sí, y la cripta de Unix, casi el mínimo común denominador en sistemas de seguridad, tiene esta característica desde 1976. Si esto es nuevo para ti, no deberías diseñar sistemas de contraseñas. Usa el bien de alguien más.
Use BCrypt - Strong Hashing Hashing para .NET y Mono. Es un único archivo .cs escrito limpiamente que continuará satisfaciendo sus necesidades a medida que las computadoras con descifrado de contraseñas se vuelven más rápidas.
Aquí hay un artículo de encriptación de cadenas con el código de ejemplo .NET
http://www.devarticles.com/c/a/VB.Net/String-Encryption-With-Visual-Basic-.NET/3/
No hay necesidad de utilizar nada sofisticado, porque cualquier persona con un poco de habilidad y determinación lo romperá de todos modos.
Personalmente, usaría algo que tenga cifrado de una vía: MD5, SHA1, etc.
Puede usar la clase FormsAuthentication con su método HashPasswordForStoringInConfigFile . Al validar al usuario, encripte la contraseña ingresada y compárela con la versión almacenada.
Si necesita descifrar la contraseña para un uso posterior y no tiene que ser SUPER segura, entonces use el método aquí:
http://support.microsoft.com/kb/307010
Está bien documentado y es fácil de entender.
Triple DES es una forma de hacerlo, siempre que quiera decir "Una contraseña que mi sistema necesita poder recuperar para acceder a un recurso". Si te refieres a que la contraseña es algo que un usuario necesita para poder acceder a tu sistema, probablemente no quieras el cifrado, solo un hash funcionará. Cuando almacena el valor de la contraseña hash, es inútil para cualquier persona con acceso directo a la base de datos, pero aún se puede usar para la autenticación . Todo lo que debes hacer es comparar el hash almacenado con un hash de la contraseña entrante. Si coinciden, entonces usted otorga acceso.
No es perfecto, de ninguna manera, pero es la forma en que el 99.999% de las personas almacena sus contraseñas.
Si desea argumentar que desea devolver la contraseña a un usuario si la pierde o la olvida, entonces no lo haga. Emítelos con una contraseña temporal (que almacena hash en el db) y haga que la cambien en el primer inicio de sesión.
Use la API de protección de datos con el usuario o la tienda de máquinas (por ejemplo, diferentes claves por cada cuenta que ejecuta su programa / servidor de bases de datos frente a una clave por máquina). Esto te ayudará a decodificar las contraseñas más adelante y no tienes que recordar ni almacenar ninguna clave de cifrado. La desventaja es que cuando reinstalas el sistema / eliminas la cuenta no podrás recuperar los datos, creo.
Según su pregunta, puedo ver dos enfoques dependiendo de por qué está almacenando la contraseña.
A. si solo necesita autenticarse usando su contraseña y nada más.
En ese caso, usar tu algoritmo que no sea reversible ( Hashing ) sería tu mejor opción. Deberá asegurarse de hacer un par de cosas:
Asegúrese de que la conexión esté encriptada al transmitir la contraseña del cliente al servidor. Esto evitará que sea olido. Esto es bastante trivial con las aplicaciones web, ya que el servidor web está haciendo un gran trabajo por usted. Si no, se vuelve mucho más complicado y es el tema de otra pregunta.
Elija un algoritmo hash sólido para evitar colisiones. Recomendaría SHA-256 incluso si proporciona un resultado más grande que SHA1 o MD5. La referencia de Microsoft sobre el uso de su implementación del algoritmo está aquí .
Sal la contraseña para evitar ataques con rainbowtable (es decir, buscar la contraseña en una tabla grande con el hash precomputado y la contraseña asociada en texto claro). La respuesta aquí (ubicada en su pregunta) da buen pseudo código en Python sobre cómo hacerlo. También hay un buen ejemplo de código .NET aquí .
B. si necesita poder leer la contraseña de cada usuario para otros fines distintos a la autenticación del usuario.
Este caso es fácil si solo estamos hablando de almacenar una contraseña (o cualquier tipo de información confidencial) en una sola computadora (servidor). Si ese es el caso, usar la API de protección de datos de Microsoft sería una buena solución ya que está vinculada a esa computadora y (dependiendo de la forma en que trabaje) el usuario bajo el cual se ejecuta la aplicación y se encarga de lo peor del trabajo para usted (crear, almacenar y usar claves). Aquí puede encontrar referencias de código de Microsoft. Si lo necesita en más de un sistema y no está dispuesto a ingresar la contraseña en cada sistema que instale en su aplicación, las cosas se vuelven mucho más complejas porque necesita implementar gran parte de ellas desde cero. Ese sería el tema de otra pregunta que pensaría.