Vous êtes sur la page 1sur 43

Validar Usuario y Password en C # 2005 y SQL Server

Publicado por Eduardo viernes 6 de noviembre de 2009

En este seccin mostraremos cmo validar el usuario y el password (correctamente) comprobandolo desde una base de datos de SQL Server. La tabla de ejemplo es "Customers" de la base de datos Northwind, los campos que usaremos como parametros seran "CustomerID" (Usuario) y "PostalCode" (Password), recordemos que ambos campos se encuentran dentro de la tabla "Customers". Este ejemplo realiza la comprobacin del usuario y el password ingresado a travs del formulario, al introducir ambos datos correctamente y presionando el boton ingresar la aplicacin emitira un mensaje de bienvenida junto al nombre del usuario (el nombre de usuario es el campo "CompanyName"), en caso contrario emitira un mensaje indicandote que los datos no son correctos. En primer lugar crearemos un proyecto en C Sharp 2005 (C#) y lo denominaremos DataAccess, luego pasamos a crear un windows forms al cual llamaremos frmIngreso, una vez creado el formulario agregamos los controles, al terminar de ingresar los controles necesarios el formulario debe de quedar como la siguiente figura.

Formulario frmIngreso A continuacin mostramos los "namespaces" (los cuales son declarados en la cabecera del formulario) y luego declaramos las variables que usaremos dentro de la aplicacin para la manipulacin de datos (las variables la declaramos despus de la clase del frmIngreso "public partial class frmIngreso : Form").

NameSpaces

Variables para la manipulacin de datos Una vez diseado el formulario, pasamos a codificar el evento "Click" del botn "Ingresar" al cual lo denominamos "btnIngresar", dentro de este botn realizaremos el llamado a la funcin "VerificarUser", al presionar el botn hara el envio de dos variables para la comprobacin dentro de la tabla Customers, luego de la validacin se pasara a emitir un mensaje de acuerdo a las filas obtenidas. En la siguiente figura se encuentra el cdigo del botn.
private void btnIngresar_Click(object sender, EventArgs e) { if (VerificaUser(this.txtUsuario.Text, this.txtClave.Text)) { if (Filas == 1) { MessageBox.Show( "Bienvenido " + Usu + " ", "Acceso al Sistema", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); } else { MessageBox.Show( "Los datos no son Corectos !!! ", "Acceso al Sistema", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1); }

} }

Cdigo del Evento Click del btnIngresar El siguiente paso es codificar la funcin "VerificarUser", donde evaluaremos ambas variables, primero conectaremos a la base de datos de SQL Server, despues definimos la cadena que vamos a usar para comprobar si el usuario y el password son correctos, para esto se utiliza parmetros para evitar la inyeccin de cdigo, luego defininimos el comando que vamos a ejecutar ceando los parmetros y asignandolos a los valores recibidos. Ejecutamos la consulta con ExecuteReader devolviendonos las filas obtenidas. En la siguiente figura se encuentra el cdigo de la funcin.
private bool VerificaUser(string user, string pass) { string MyUser = user.Trim(); //asignamos la cadena de conexin a la variable Str = ("Server=Srv01;Database=Northwind;uid=sa;pwd=;"); //instanciamos la variable conexion Cn = new SqlConnection(); //declaramos la conexion Cn.ConnectionString = Str; System.Text.StringBuilder Sel = new System.Text.StringBuilder(); Sel.Append("SELECT * FROM Customers "); //Count(*) Sel.Append("WHERE CustomerID = @USER AND PostalCode = @PASS "); Cm = new SqlCommand(Sel.ToString(), Cn); Cm.Parameters.Add("@USER", SqlDbType.NChar, 5); Cm.Parameters.Add("@PASS", SqlDbType.NVarChar, 10); Cm.Parameters["@USER"].Value = MyUser; Cm.Parameters["@PASS"].Value = pass; Cn.Open(); Dr = Cm.ExecuteReader(); Filas = Convert.ToInt32(Dr.HasRows); //obtiene las filas de la consulta if (Dr.Read()) Usu = Convert.ToString(Dr[1]); Cn.Close(); Dr.Close(); return true; }

Cdigo de la Funcin VerificaUser Al finalizar toda la codificacin, ejecutamos la aplicacin e ingresamos el Usuario y el Password, si los datos ingresados son correctos, la aplicacin te emite un mensaje de bienvenido junto al usuario (ver penultima figura), en caso contrario emitira un mensaje de error (ver ultima figura). A continuacin mostramos el formulario ejecutado.

Formulario con los Datos Ingresados

Mensaje de Bienvenida (Acceso Correcto)

Mensaje de Error (Acceso Incorrecto)

Cmo... en .NET Iniciar la aplicacin solo al introducir la clave correcta (C#)


O como iniciar una aplicacin con clave de acceso. Cdigo para C# (2002/2003)

Ejemplo para C# (2002/2003) de cmo iniciar una aplicacin en la que se le pide al usuario una clave de acceso. Si la clave es correcta se mostrar el formulario principal, y si la clave no es correcta se cerrar la aplicacin. Tambin te muestro cmo permitir ms de un intento para introducir esa clave, y si superas ese nmero, se acaba la aplicacin.

Publicado el 06/Abr/2006 Actualizado el 29/Nov/2006 Autor: Guillermo 'guille' Som

Introduccin:
Esto es algo que mucha gente pregunta, pero que no tena por aqu publicado, as que ya era hora. El tema es que tenemos una aplicacin de tipo "desktop" (Windows.Forms) en la que necesitamos que el usuario introduzca una clave para poder usarla. El problema con el que se encuentran algunos de los que intentan hacer esto es que escriben el cdigo en el formulario principal y si la clave no es correcta, lo cierran, pero debido a como maneja Visual Studio .NET el tema de los formularios, al cerrar ese formulario principal, se cierra toda la aplicacin... incluso si la clave es correcta! La solucin es crear un formulario para comprobar esa clave, a ese formulario lo llamamos justo al iniciarse la aplicacin, de forma que si la clave introducida es correcta, se muestre el formulario principal, y si no es correcta, cerramos la aplicacin. Debido a que Visual Basic y C# manejan de forma diferente el cdigo insertado automticamente en el formulario, he preferido separar en dos artculos este "truco", as los desarrolladores de C# no tendrn que aguantar las particularidades de Visual Basic .NET y viceversa, adems de que as queda ms claro todo al no tener que explicar cosas diferentes

en cada caso, ya que esos dos lenguajes en el fondo van a usar el mismo cdigo (o casi), pero la forma de implementarlo ser diferente. Tambin he puesto independiente el cdigo para las versiones anteriores a Visual Studio 2005 ya que en el caso de Visual Basic 2005 hay que usar otros cuadros de dilogos y con esta separacin tambin quedar ms claro todo. El hacer estas "separaciones" segn el lenguaje y las versiones de esos lenguajes, es porque principalmente los que lean esto sern aquellos que estn empezando a programar, y cuanto ms claro est todo, mejor se aprende.

Aqu te dejo los links a los otros artculos:


Este otro es para Visual C# 2005 (.NET 2.0) Este link es para el cdigo de Visual Basic .NET (2002/2003) (.NET 1.x) Pulsa aqu, si te interesa ver el cdigo y la explicacin para Visual Basic 2005 (.NET 2.0) Si quieres saber cmo hacer esto mismo pero usando una base de datos (VB2003) Si quieres saber cmo hacer esto mismo pero usando una base de datos (C# 2003)

Crear el proyecto de ejemplo:


Los pasos que tenemos que dar para crear la aplicacin de ejemplo son los siguientes:
1. Crea un nuevo proyecto del tipo Windows.Forms (Aplicacin para Windows). 2. Tendremos un formulario llamado Form1, por simplicidad vamos a dejarle ese mismo nombre (Form1). 3. Aade a ese formulario una etiqueta en la debes escribir lo que quieras, simplemente es para que sepas que es el formulario principal de tu aplicacin. Por supuesto en este formulario es donde tendrs que hacer todo lo que tu aplicacin deba hacer. 4. Aade un segundo formulario al que le dars el nombre FormAcceso, inicialmente se llamar Form2, pero si le cambias el nombre justo al aadirlo, ser ms cmodo. 5. En ese formulario de acceso, que ser el que usemos para pedir la clave, aade una etiqueta, una caja de textos y dos botones. 6. Modifica la propiedad FormBorderStyle para que tenga el valor FixedDialog. 7. Asigna un valor False a las propiedades ControlBox, MaximizeBox y MInimizeBox. 8. A la caja de textos dale el nombre txtClave y si no quieres que se vea la clave mientras se escribe, asigna un * a la propiedad PasswordChar. 9. A los botones, le asignas los nombres btnAceptar y btnCancelar, y los textos Aceptar y Cancelar respectivamente. 10. Sita esos controles donde ms te guste, por ejemplo, puede tener un aspecto como el mostrado en la figura 1:

Figura 1. El formulario para la clave de acceso


11. Haz dobleclick en el botn de Cancelar y sustityelo por el siguiente cdigo, en el que asignamos el valor Cancel al valor devuelto por la propiedad DialogResult que es el valor que devuelve el mtodo ShowDialog de ese formulario (ms abajo vers cmo se usa), en lugar de cerrar el formulario, lo ocultamos para que todo funcione mejor.
private void btnCancelar_Click(System.Object sender, System.EventArgs e) { this.DialogResult = DialogResult.Cancel; Hide(); }

12. Haz dobleclick en el botn Aceptar y escribe el cdigo de ms abajo, en el que hacemos la comprobacin de si la clave escrita es la correcta, en este caso 123456, si es as, asignamos un valor OK y si no lo es, asignamos cualquier otro valor, ya que en nuestro cdigo de validacin, daremos como que la clave es correcta si tiene el valor OK. Aqu tambin ocultamos el formulario de las claves con Hide para que contine la ejecucin del programa y vuelva al cdigo desde el que se ha mostrado este formulario.
private void btnAceptar_Click(System.Object sender, System.EventArgs e) { if( txtClave.Text == "123456" ) { this.DialogResult = DialogResult.OK; } else { this.DialogResult = DialogResult.No; } Hide(); }

13. En ambos casos, se supone que los nombres de los controles son como te he comentado, si no es as, pues debers cambiar los nombres de los controles, as que, te recomiendo que para este ejemplo uses los nombres que te indico. 14. Una vez hecho esto, ya tenemos el cdigo del formulario que pide la clave de acceso. 15. Tal como est el cdigo solo tendrs un intento para escribir correctamente la clave, despus veremos cmo cambiar el cdigo para que tengas el nmero de intentos que quieras. 16. Ahora vamos a modificar el cdigo del formulario principal, (Form1).

17. Busca el cdigo del mtodo Main y sustityelo por este otro:
[STAThread] static void Main() { FormAcceso fAcceso = new FormAcceso(); if( fAcceso.ShowDialog() == System.Windows.Forms.DialogResult.OK ){ fAcceso.Close(); Application.Run(new Form1()); } }

18. Con esto lo que hacemos es cargar el formulario que pide la clave, y si escribes la clave correcta, se cargar el formulario principal (Form1), si no es correcta, el valor devuelto por ShowDialog ser distinto de OK, por tanto no se carga en memoria el formulario principal y se acabar la aplicacin. Para cargar el formulario principal usamos Application.Run al que le pasamos el formulario que queremos que se utilice como inicio, es decir, ese formulario ser el que mantenga la aplicacin abierta, en cuanto se cierre el formulario principal (Form1) la aplicacin finalizar. 19. En C#, a diferencia de Visual Basic, no tenemos que indicarle que use el mtodo Main para iniciar la aplicacin, ya que siempre es as. 20. Ahora puedes probar a ver si todo funciona bien, para ello, pulsa en F5 y te mostrar el formulario de acceso, escribe 123456 y pulsa en Aceptar, vers que te muestra el formulario principal (Form1). 21. Si pulsas en Cancelar o escribes mal la clave, se cerrar el programa.

Mejoras al cdigo
Ahora vamos a mejorar un poco el cdigo. Lo primero que vamos a hacer es asignar a los botones del formulario que pide la clave la funcionalidad que normalmente suelen tener, aunque esto lo dejo a tu gusto, esa funcionalidad es que al pulsar Intro sea como si pulsramos en el botn Aceptar, de esta forma, el usuario escribe la clave y pulsa Intro en tener que buscar el botn y hacer click, aunque tambin puede hacerlo y todo funcionar igual. La otra caracterstica es que el botn Cancelar se asocie con la tecla ESC, de forma que si el usuario pulsa esa tecla sea lo mismo que si hubiera pulsando en Cancelar. Para conseguir esto, debes hacer lo siguiente:
1. Muestra el formulario de la clave de acceso y pulsa una vez en cualquier parte del formulario, pero no en ninguno de los controles. 2. Ahora en la ventana de propiedades (si no la ves, pulsa F4), selecciona la propiedad AccepButton y de la lista desplegable (ver la figura 2) selecciona btnAceptar.

Figura 2. Asignar el botn predeterminado


3. Una vez hecho eso, vers que el botn Aceptar tiene un borde ms oscuro, eso indica que es el botn predeterminado, por tanto ser el que reciba la pulsacin de la tecla Intro. 4. Ahora selecciona la propiedad CancelButton y de la lista selecciona btnCancelar. 5. Ya tienes esa funcionalidad, que puedes probar si inicias la aplicacin (F5) y despus de escribir la clave pulsas INTRO, vers que no tienes que hacer click en el botn Aceptar. 6. Lo mismo ocurre si pulsas la tecla ESC, vers que se cierra la aplicacin aunque la clave sea correcta, ya que en realidad es como si hubieras pulsado en el botn Cancelar.

Sigamos con las mejoras:


Permitir varios intentos fallidos antes de cerrar la aplicacin

Como es posible que el usuario se equivoque al escribir o se olvide de la clave, vamos a darle algunas oportunidades ms, por ejemplo tres. Para hacer esto, tenemos que modificar el cdigo del formulario de acceso, por tanto muestra el panel del cdigo de ese formulario (FormAcceso) y antes del cdigo que aadimos al principio, escribe esto:
private int veces = 0; const int NumeroIntentos = 3;

La constante NumeroIntentos tendr el valor de las veces que vamos a permitir que escriba la clave antes de darlo como cosa perdida y cerrar la aplicacin. Ahora escribe esto en el mtodo del botn Aceptar, de forma que esto sea el nuevo cdigo:
private void btnAceptar_Click(System.Object sender, System.EventArgs e) { if( txtClave.Text == "123456" ) { this.DialogResult = DialogResult.OK; } else { // Permitir varios intentos veces = veces + 1; if( veces < NumeroIntentos ) { Label1.Text = "Quedan " + (NumeroIntentos - veces) + " intentos"; return; } this.DialogResult = DialogResult.No; } Hide(); }

Lo que hacemos es incrementar el contenido de la variable veces cada vez que se pulse en Aceptar, pero cuando la clave que escribimos no es la correcta, ya que si es correcta no hay que dar ms intentos, je, je. Si el valor de esa variable en menor que el nmero mximo de intentos, modificamos el contenido de la etiqueta que hay junto a la caja de textos (Label1) para que muestre los intentos que quedan. Si superamos ese nmero se volver al otro cdigo y se acabar la aplicacin.

Y esto es todo, espero que te haya resultado sencillo de comprender, y si ya tenas ms experiencia, espero que sepas perdonar que lo haya explicado tan "paso a paso". Que lo disfrutes! Nos vemos. Guillermo

C#: Autenticar Usuario con Formularios y Base de Datos


Publicado el octubre 4, 2008 por tydw

Esta es la continuacion del tutorial anterior. En el cual usabamos el web.config, ahora lo haremos contra un abase de datos. Usaremos Visual Studio 2005 mas Framework .NET 2.0. El lenguaje lo cambiaremos a C#. Crearemos un nuevo sitio web en lenguaje C#. Le agregaremos una pagina que llamaremos login.aspx en el cual le agregaremos el control de Login que trae la Barra de Herramientas.

Los colores y fuente de letras de la caja del Login queda a gusto del programador lo mencionamos en el tutorial anterior.

, como

Luego abriremos nuestro archivo web.config y agregaremos el siguiente codigo que le indicara a nuestro sitio web que todas las paginas necesitaran auntentificarse antes ser accesadas. <authentication mode=Forms> <forms name=miFormulario loginUrl=login.aspx protection=All path=/ timeout=30 /> </authentication>

<authorization> <deny users =? /> <allow users = * /> </authorization> Ahora iremos con la pagina logina.spx. En el evento Login1_Authenticate agregaremos este codigo: protected void Login1_Authenticate(object sender, AuthenticateEventArgs e) { if (ValidateUser(Login1.UserName, Login1.Password)) { FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet ); } } Aqui dejamos la entrada del usuario dependiendo de una funcion creada por nosotros (ValidateUser). La cual validara el usuario y contrasea contra una base de datos. Como sera ORACLE, debemos agregar la referencia del cliente de .NET para esta base.

Se tiene que agregar la llamada a la libreria al inicio de la pagina login.aspx.cs: System.Data.OracleClient; El codigo de esta funcion es el que sigue: private bool ValidateUser(string userName, string passWord) { string lookupPassword = null; string sql = null;

OracleConnection oraConn = new OracleConnection(Data Source=miservidor;User Id=miusuario;Password=mipassword); sql = select clave from tabla_usuarios where login = + userName + ; OracleCommand oraCMD = new OracleCommand(sql, oraConn); oraConn.Open(); //recuperamos la password de la base lookupPassword = (string)oraCMD.ExecuteScalar(); oraConn.Close(); //si no hay resultados, se devuelve falso if (null == lookupPassword) { return false; } //se compara la password de la base con la digitada, usando case sensitive return (0 == string.Compare(lookupPassword.Trim(), passWord.Trim(), false)); } Ahora iremos sobre el codigo CS de la pagina Default.aspx. Vamos a mostrar algunos datos que ya tenemos por el metodo de autenticacion que estan en las credenciales. protected void Page_Load(object sender, EventArgs e) { if (HttpContext.Current.User.Identity.IsAuthenticated) { //desplegamos la informacion de las credenciales Response.Write(Bienvenido : + User.Identity.Name + + Tipo de Autentificacion Usada : + User.Identity.AuthenticationType + ); } } A la pagina default.aspx le agregaremos un boton para salir de la zona de aunteticacion. El boton lo denominaremos SignOut y le asinaremos el sgte. codigo: protected void cmdSignOut_Click(object sender, EventArgs e) { //se borra la cookie de autenticacion FormsAuthentication.SignOut();

//se redirecciona al usuario a la pagina de login Response.Redirect(Request.UrlReferrer.ToString()); } Cuando ejecutemos nuestro sitio web, nos pedira auntenticarnos, al darles los datos correctos de la base de datos veremos la pagina default.aspx, con los datos del usuario.

ASP .NET: Autenticar Usuario con Formularios


Publicado el agosto 8, 2008 por tydw

Entregare un pequeo tutorial para autenticar usuarios basado en formularios. Usaremos Visual Studio 2005 mas Framework .NET 2.0, ademas le daremos un vistazo al manejo de variables de sesiones. Manejaremos los usuarios del sitio web via web.config. Primero que nada crearemos un nuevo sitio web en lenguaje Visual Basic. Le agregaremos una pagina que llamaremos login.aspx en el cual le agregaremos el control de Login que trae la Barra de Herramientas.

Los colores y fuente de letras de la caja del Login queda a gusto del programador Luego abriremos nuestro archivo web.config y agregaremos el siguiente codigo que le indicara a nuestro sitio web que todas las paginas necesitaran auntentificarse antes ser accesadas.
<authorization> <deny users=?/></authorization>

<authentication mode=Forms> <forms name=frm path=/ loginUrl=login.aspx protection=All timeout=30> <dentials passwordFormat=Clear> <user name=user01 password=pass1/> <user name=user02 password=pass2/> </credentials> </forms> </authentication>

Este codigo se puede colocar despues de la etiqueta


<system.web>

En el codigo anterior agregamos 2 usuarios que seran los permitidos a entrar al sitio asi como sus contraseas. Ahora iremos con la pagina logina.spx. En el evento Login1_Authenticate agregaremos este codigo:
If FormsAuthentication.Authenticate(Login1.UserName.ToString, Login1.Password.ToString) Then Session.Add(id_user, 12345678-9) FormsAuthentication.RedirectFromLoginPage(Login1.UserName.ToString, Login1.RememberMeSet) End If

Aqui hicimos 2 cosas: Primero verificar contra el web.config el usuario y password que ingresamos. Si estan correctos, crearemos una variable de sesion llamada id_user que tendra el valor 12345678-9, y luego redireccionaremos a la pagina Default.aspx que sera la pagina por defecto. Tambien funcionara si queremos entrar a otra pagina del sitio en particular (lo veremos mas adelante). Ahora iremos sobre el codigo VB de la pagina Default.aspx. Vamos a mostrar algunos datos que ya tenemos por el metodo de autenticacion que estan en las credenciales. Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Response.Write(<h1>Pagina Principal</h1>)

verificamos autenticacion If User.Identity.IsAuthenticated Then desplegamos la informacion de las credenciales displayCredentials.Text = Bienvenido : & User.Identity.Name & & _ Tipo de Autentificacion Usada : & User.Identity.AuthenticationType & End If End Sub

A la pagina default.aspx le agregaremos un boton para salir de la zona de aunteticacion. El boton lo denominaremos SignOut y le asinaremos el sgte. codigo: Protected Sub cmdSignOut_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdSignOut.Click borrar sesion Session.Clear() Session.Abandon() delete the users auth cookie and sign out FormsAuthentication.SignOut() redirect the user to their referring page Response.Redirect(Request.UrlReferrer.ToString()) End Sub Aqui cerraremos la sesion de variables y la credencial que nos dio el sitio y nos envia automaticamente a la pagina de login. Ahora agregaremos una pagina que llamara reportes.aspx, la cual sera llamada por un hipervinculo desde la pagina default.aspx. Esta pagina mostrara ademas de los datos del usuario, el valor de la variable de sesion. Pero antes debemos agregar una seccion para nuestras variables de sesion en el web.config para su uso. Agregamo lo sgte. en la seccion Session State: <sessionState mode=InProc stateConnectionString=tcpip=127.0.0.1:42424 sqlConnectionString=data source=127.0.0.1;Trusted_Connection=yes cookieless=false timeout=1 /> Nuestras variables duraran 1 minuto para diferenciarla del timeout del login que es de 30 minutos.

En la pagina de reportes, ademas agregaremos un boton para volver a la pagina principal, se llamara btnVolver y el codigo de la pagina sera el sgte: Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Response.Write(<h1>menu de reportes de gestion</h1>) If User.Identity.IsAuthenticated Then datos de la credencial Response.Write(Bienvenido : & User.Identity.Name & & _ Tipo de Autentificacion Usada : & User.Identity.AuthenticationType & ) End If Response.Write( id usuario = & Session(id_user)) End Sub Protected Sub btnVolver_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnVolver.Click Response.Redirect(default.aspx, False) End Sub Cuando ejecutemos nuestro sitio web, nos pedira auntenticarnos, al darles los datos correctos veremos la pagina default.aspx, con los datos del usuario. Al hacer click en el hipervinculo que nos llevara a la pagina reportes.aspx y mostrara nuestra variable de sesion. Si esperan mas de 1 minuto en esta pagina y luego hacen un refresh, veran que el valor de nuestra variable desaparece por el minuto que le dimos de vida. A continuacion la secuencia del sitio.

Al ir a la pagina de los reportes

Y si esperan mas de 1 minuto, el valor de la variable de sesion desaparece.

Prueben y comenten si tienen problemas. Links: C#: Autenticar Usuarios con Formularios y Bases de Datos

Respuesta: Encriptar y desencriptar pass con c# Ojo calcular un Hash no es encriptar, el hash por definicion no tiene vuelta atras una vez que calculas el valor hash de entrada no hay forma de hacer lo opuesto. Que no es lo mismo que comparar un hash almacenado con un hash calculado que hacen las mayorias de los scripts y codigos en el mundo. PD: Es como la 10 vez que discuto algo asi , pero es bueno saberlo

Adicionalmente En todo caso necesitas utilizar el namespace System.Security.Cryptography y usar uno de los tantos CryptoProviders y usar un CryptoStream para poder realizar un proceso encripta/desencripta __________________ Respuesta: Encriptar y desencriptar pass con c# Calculas el hash de no se Primera vez el usuario se registra y guarda el hash de una contrasenia Original Hash Gato123 = BAD12327362986387236827361ABCD cuando el usuario quiera hacer login tu deberas hacer el mismo calculo de hash y comparar tu resultado contra el registrado Original Hash en BD Hash al hacer login Gato345 BAD12327362986387236827361ABCD BAD123ABCD863457236827361ABCD como no hay match no es el mismo password Gato123 BAD12327362986387236827361ABCD BAD12327362986387236827361ABCD si fuera el mismo que registro originalmente entonces valida su credencial. PD: Solo hacemos incomprensible al ojo humano el valor guardado, pero al no ser reversible no se le puede llamara encriptacion. PD: Ejemplo ilustrativo

///////////////////////////////////////////////////////////////////////// ////// // SAMPLE: Symmetric key encryption and decryption using Rijndael algorithm. // // To run this sample, create a new Visual C# project using the Console // Application template and replace the contents of the Class1.cs file with // the code below. // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, // EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. // // Copyright (C) 2002 Obviex(TM). All rights reserved. // using System; using System.IO; using System.Text; using System.Security.Cryptography; /// <summary> /// This class uses a symmetric key algorithm (Rijndael/AES) to encrypt and /// decrypt data. As long as encryption and decryption routines use the same /// parameters to generate the keys, the keys are guaranteed to be the same. /// The class uses static functions with duplicate code to make it easier to /// demonstrate encryption and decryption logic. In a real-life application, /// this may not be the most efficient way of handling encryption, so as /// soon as you feel comfortable with it - you may want to redesign this class. /// </summary> public class RijndaelSimple { /// <summary> /// Encrypts specified plaintext using Rijndael symmetric key algorithm /// and returns a base64-encoded result. /// </summary> /// <param name="plainText"> /// Plaintext value to be encrypted. /// </param> /// <param name="passPhrase"> /// Passphrase from which a pseudo-random password will be derived. The /// derived password will be used to generate the encryption key. /// Passphrase can be any string. In this example we assume that this /// passphrase is an ASCII string. /// </param> /// <param name="saltValue">

/// Salt value used along with passphrase to generate password. Salt can /// be any string. In this example we assume that salt is an ASCII string. /// </param> /// <param name="hashAlgorithm"> /// Hash algorithm used to generate password. Allowed values are: "MD5" and /// "SHA1". SHA1 hashes are a bit slower, but more secure than MD5 hashes. /// </param> /// <param name="passwordIterations"> /// Number of iterations used to generate password. One or two iterations /// should be enough. /// </param> /// <param name="initVector"> /// Initialization vector (or IV). This value is required to encrypt the /// first block of plaintext data. For RijndaelManaged class IV must be /// exactly 16 ASCII characters long. /// </param> /// <param name="keySize"> /// Size of encryption key in bits. Allowed values are: 128, 192, and 256. /// Longer keys are more secure than shorter keys. /// </param> /// <returns> /// Encrypted value formatted as a base64-encoded string. /// </returns> public static string Encrypt(string plainText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize) { // Convert strings into byte arrays. // Let us assume that strings only contain ASCII codes. // If strings include Unicode characters, use Unicode, UTF7, or UTF8 // encoding. byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector); byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue); // Convert our plaintext into a byte array. // Let us assume that plaintext contains UTF8-encoded characters. byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); // First, we must create a password, from which the key will be derived. // This password will be generated from the specified passphrase and // salt value. The password will be created using the specified hash

// algorithm. Password creation can be done in several iterations. PasswordDeriveBytes password = new PasswordDeriveBytes( passPhrase, saltValueBytes, hashAlgorithm, passwordIterations); // Use the password to generate pseudo-random bytes for the encryption // key. Specify the size of the key in bytes (instead of bits). byte[] keyBytes = password.GetBytes(keySize / 8); // Create uninitialized Rijndael encryption object. RijndaelManaged symmetricKey = new RijndaelManaged(); // It is reasonable to set encryption mode to Cipher Block Chaining // (CBC). Use default options for other symmetric key parameters. symmetricKey.Mode = CipherMode.CBC; // Generate encryptor from the existing key bytes and initialization // vector. Key size will be defined based on the number of the key // bytes. ICryptoTransform encryptor = symmetricKey.CreateEncryptor( keyBytes, initVectorBytes); // Define memory stream which will be used to hold encrypted data. MemoryStream memoryStream = new MemoryStream(); // Define cryptographic stream (always use Write mode for encryption). CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write); // Start encrypting. cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); // Finish encrypting. cryptoStream.FlushFinalBlock(); // Convert our encrypted data from a memory stream into a byte array. byte[] cipherTextBytes = memoryStream.ToArray(); // Close both streams. memoryStream.Close(); cryptoStream.Close(); // Convert encrypted data into a base64-encoded string.

string cipherText = Convert.ToBase64String(cipherTextBytes); // Return encrypted string. return cipherText; } /// <summary> /// Decrypts specified ciphertext using Rijndael symmetric key algorithm. /// </summary> /// <param name="cipherText"> /// Base64-formatted ciphertext value. /// </param> /// <param name="passPhrase"> /// Passphrase from which a pseudo-random password will be derived. The /// derived password will be used to generate the encryption key. /// Passphrase can be any string. In this example we assume that this /// passphrase is an ASCII string. /// </param> /// <param name="saltValue"> /// Salt value used along with passphrase to generate password. Salt can /// be any string. In this example we assume that salt is an ASCII string. /// </param> /// <param name="hashAlgorithm"> /// Hash algorithm used to generate password. Allowed values are: "MD5" and /// "SHA1". SHA1 hashes are a bit slower, but more secure than MD5 hashes. /// </param> /// <param name="passwordIterations"> /// Number of iterations used to generate password. One or two iterations /// should be enough. /// </param> /// <param name="initVector"> /// Initialization vector (or IV). This value is required to encrypt the /// first block of plaintext data. For RijndaelManaged class IV must be /// exactly 16 ASCII characters long. /// </param> /// <param name="keySize"> /// Size of encryption key in bits. Allowed values are: 128, 192, and 256. /// Longer keys are more secure than shorter keys. /// </param> /// <returns> /// Decrypted string value. /// </returns> /// <remarks> /// Most of the logic in this function is similar to the Encrypt /// logic. In order for decryption to work, all parameters of this function

/// - except cipherText value - must match the corresponding parameters of /// the Encrypt function which was called to generate the /// ciphertext. /// </remarks> public static string Decrypt(string cipherText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize) { // Convert strings defining encryption key characteristics into byte // arrays. Let us assume that strings only contain ASCII codes. // If strings include Unicode characters, use Unicode, UTF7, or UTF8 // encoding. byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector); byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue); // Convert our ciphertext into a byte array. byte[] cipherTextBytes = Convert.FromBase64String(cipherText); // First, we must create a password, from which the key will be // derived. This password will be generated from the specified // passphrase and salt value. The password will be created using // the specified hash algorithm. Password creation can be done in // several iterations. PasswordDeriveBytes password = new PasswordDeriveBytes( passPhrase, saltValueBytes, hashAlgorithm, passwordIterations); // Use the password to generate pseudo-random bytes for the encryption // key. Specify the size of the key in bytes (instead of bits). byte[] keyBytes = password.GetBytes(keySize / 8); // Create uninitialized Rijndael encryption object. RijndaelManaged symmetricKey = new RijndaelManaged(); // It is reasonable to set encryption mode to Cipher Block Chaining // (CBC). Use default options for other symmetric key parameters. symmetricKey.Mode = CipherMode.CBC; // Generate decryptor from the existing key bytes and initialization // vector. Key size will be defined based on the number of the key // bytes. ICryptoTransform decryptor = symmetricKey.CreateDecryptor( keyBytes,

initVectorBytes); // Define memory stream which will be used to hold encrypted data. MemoryStream memoryStream = new MemoryStream(cipherTextBytes); // Define cryptographic stream (always use Read mode for encryption). CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read); // Since at this point we don't know what the size of decrypted data // will be, allocate the buffer long enough to hold ciphertext; // plaintext is never longer than ciphertext. byte[] plainTextBytes = new byte[cipherTextBytes.Length]; // Start decrypting. int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); // Close both streams. memoryStream.Close(); cryptoStream.Close(); // Convert decrypted data into a string. // Let us assume that the original plaintext string was UTF8encoded. string plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); // Return decrypted string. return plainText; } } /// <summary> /// Illustrates the use of RijndaelSimple class to encrypt and decrypt data. /// </summary> public class RijndaelSimpleTest { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main(string[] args) { string plainText = "Hello, World!"; // original plaintext

string string string string string int number string bytes int or 128

passPhrase saltValue

= "Pas5pr@se"; = "s@1tValue";

// can be any // can be any // can be "MD5" // can be any

hashAlgorithm = "SHA1"; passwordIterations = 2; initVector keySize

= "@1B2c3D4e5F6g7H8"; // must be 16 = 256; // can be 192

Console.WriteLine(String.Format("Plaintext : {0}", plainText)); string cipherText = RijndaelSimple.Encrypt(plainText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize);

Console.WriteLine(String.Format("Encrypted : {0}", cipherText)); plainText = RijndaelSimple.Decrypt(cipherText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize);

Console.WriteLine(String.Format("Decrypted : {0}", plainText)); } } // // END OF FILE ///////////////////////////////////////////////////////////////////////// //////

Encriptar cadenas de texto en C# (C Sharp)

Comenzar con la definicin de encriptar, es un trmino usado para cifrar mensajes de tal forma que sean ilegibles a simple vista o al leerlos, en C Sharp se puede desarrollar una pequea aplicacin para encriptar y decriptar (lo inverso de encriptar) mensajes de una manera sencilla usando la plataforma de .NET Framework. Cree un proyecto en Windows Forms como lenguaje de programacin en C# y un formulario similar a este:

Dependiendo de como nombre a los elementos, estos son a los que me referir en el cdigo para que pueda cambiar el nombre de dichos elementos: encInput: Entrada de texto a encriptar. encOutput: Salida de texto encriptada. decInput: Entrada de cdigo encriptado. decOutput: Salida de cdigo encriptado a texto. btnEncrypt: Botn para encriptar. btnDecrypt: Botn para decriptar. Y ya el nombre de los siguientes elementos puede ser distinto, especifico esto porque estos son los nombres de los controles que va a usar el cdigo y evitar errores por otros nombres. En la parte del encabezado, importe los siguientes namespaces (Espacios de nombres):

-----Inicia el Cdigo----using System.Security.Cryptography; using System.IO; -----Finaliza el Cdigo----Despues, abajo de la clase, escriba el siguiente cdigo: private RSACryptoServiceProvider alg; Y debajo de InitializeComponent(); Escriba lo siguiente: alg = new RSACryptoServiceProvider(); De modo que quede as:

-----Inicia el Cdigo----public partial class MainWindow : Form { private RSACryptoServiceProvider alg; public MainWindow() { InitializeComponent(); alg = new RSACryptoServiceProvider(); }

} -----Finaliza el Cdigo----Ahora ya est declarado el provedor de servicios de criptografa que es RSA y est en la biblioteca System. Dentro de la clase, agregue las siguientes funciones de encripcin: -----Inicia el Cdigo----private void CreateKey(string file) { string key = alg.ToXmlString(true); FileStream fs = new FileStream(file, FileMode.Create); StreamWriter sw = new StreamWriter(fs); sw.Write(file); sw.Close(); } private RSACryptoServiceProvider LoadKey(string file) { FileStream fs = new FileStream(archivo, FileMode.Open); StreamReader sr = new StreamReader(fs); string key = sr.ReadToEnd(); sr.Close(); alg.FromXmlString(key); return alg; } private byte[] Encrypt(byte[] input) { CreateKey("key.xml") ; byte[] output = alg.Encrypt(input, false); return output; } private byte[] Decrypt(byte[] input) { alg = LoadKey("key.xml") ; byte[] output = alg.Decrypt(input, false); return output; } -----Finaliza el Cdigo----Ya que todas las funciones estn declaradas, vamos a proceder para que los botones sigan

sus respectivas instrucciones. Ahora vaya al diseador y d doble clic al botn de Encriptar, aparecer un cdigo como este: -----Inicia el Cdigo----private void btnEncrypt_Click(object sender, EventArgs e) { //Aqu escriba el cdigo del siguiente paso... } -----Finaliza el Cdigo----Escriba lo siguiente: -----Inicia el Cdigo----byte[] OriginalText = System.Text.Encoding.UTF8.GetBytes(encInput.Text); EncOutput.Text = Convert.ToBase64String(Encrypt(OriginalText)); -----Finaliza el Cdigo----Tambien en el botn de Decriptar d doble clic para que pueda asignarle un mtodo, ya que aparece lo siguiente: -----Inicia el Cdigo----private void btnDecrypt_Click(object sender, EventArgs e) { //Aqu escriba el cdigo del siguiente paso... } -----Finaliza el Cdigo----Ahora escriba el siguiente mtodo: -----Inicia el Cdigo----try { byte[] OriginalText = Convert.FromBase64String(decInput.Text); decOutput.Text = System.Text.Encoding.UTF8.GetString(Decrypt(OriginalText)); } catch { MessageBox.Show("Imposible descifrar cdigo, llave de acceso incorrecta o texto a decriptar errneo." , "Error al decriptar", MessageBoxButtons.OK,

MessageBoxIcon.Warning); } -----Finaliza el Cdigo-----

TripleDES - Un ejemplo practico en C#


En Devjoker hemos publicado ya algunos articulos sobre encriptacin, desde como implementar un sencillo algoritmo propio con aritmetica modular (http://www.devjoker.com/contenidos/Articulos/2/Una-clase-sencilla-paraencriptar-cadenas.aspx) hasta los estupendos articulos de Pablo Gumpert sobre como utilizar el algoritmo TRIPLEDES:

http://www.devjoker.com/contenidos/Articulos/276/-Como-encriptar-texto-y-variablesusando-algoritmos-estandard-como-DES-o-TRIPLEDES.aspx http://www.devjoker.com/contenidos/Articulos/280/Desencriptar-Texto-y-variables-conNET-VB-y-C-(segunda-parte).aspx

Tambin de Pablo Gumpert es el articulo sobre encriptacin en SQL Server:

http://www.devjoker.com/contenidos/Articulos/82/Como-encriptar-o-cifrar-cadenas-ycampos-en-SQL-server-2005-ENCRYPTBYPASSPHRASE-y-DECRYPTBYPASSPHRASE.aspx

Este articulo pretende, por un lado servir de recopilacin de enlaces de criptografia de devjoker, y por otro mostrar un ejemplo practico de como implementar la encriptacin a travs del algoritmo TRIPLEDES. En este ejemplo vamos a escribir una clase, en C# que encripta un texto introducido por el usuario y posteriormente lo desencripta. La utilidad del programa radica en mostrar como se encriptan los datos y como posteriormente se recuperan. Lo primero que hacemos es definir una clase, a la que llamamos TripleDESUtil, y definimos dos propiedades, IV y Key. Estas propiedades son de extrema importancia, ya que sin ellas no podrmos descifrar nada. Es importante que en un sistema real estas propiedades sean persistentes o se lean de algn lugar seguro.

class TripleDESUtil { public byte[] IV { get; set; }

public byte[] Key { get; set; } }

El ejemplo lo he realizado con el framework 3.5, por lo que hemos declarado las propiedades de forma abreviada. Si trabajais con un framework anterior tendreis que implementar las propiedades manualmente. A continuacin, escribirmos el metodo de encriptacin. Utilizamos las clases que nos proporciona el .NET framework para utilizar el algoritmo TRIPLEDES. Estan definidas en el namespace System.Security.Cryptography y son:

TripleDESCryptoServiceProvider, que permite crear un objeto que implemente la interfaz ICryptoTransform y encardo de manejar la clave(key) y el desplazamiento(IV). ICryptoTransform, que define las operaciones bsicas de las transformaciones criptogrficas. CryptoStream, Stream donde escribiremos el resultado de la encriptacin.

public byte[] Encriptar( string cadenaOrigen) { UTF8Encoding encoding = new UTF8Encoding(); byte[] message = encoding.GetBytes(cadenaOrigen);

TripleDESCryptoServiceProvider criptoProvider = new TripleDESCryptoServiceProvider();

IV = criptoProvider.IV; Key = criptoProvider.Key;

ICryptoTransform criptoTransform = criptoProvider.CreateEncryptor(Key, IV);

MemoryStream memoryStream = new MemoryStream();

CryptoStream cryptoStream = new CryptoStream(memoryStream, criptoTransform, CryptoStreamMode.Write);

cryptoStream.Write(message, 0, message.Length); // cryptoStream.Flush(); cryptoStream.FlushFinalBlock();

byte[] encriptado = memoryStream.ToArray();

string cadenaEncriptada = encoding.GetString(encriptado); Console.WriteLine("Texto encriptado {0}", cadenaEncriptada );

return encriptado; }

El metodo muestra en pantalla el resultado de la encriptacin, por supuesto esta parte la eliminariamos en una implementacin real. La funcin para desencriptar es muy similar, salvo que al crear la transformacin ICryptoTransform utilizamos el mtodo CreateDecryptor y que al instanciar el CryptoStream le indicamos que el mtodo es de lectura, a travs de la enumeracin CryptoStreamMode.Read.
Posteriormente utilizamos un StreamReader para obtener el texto descifrado.

public string DesEncriptar(byte[] message) { TripleDES cryptoProvider = new TripleDESCryptoServiceProvider();

ICryptoTransform cryptoTransform = cryptoProvider.CreateDecryptor(Key,IV );

MemoryStream memoryStream = new MemoryStream(message);

CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Read);

StreamReader sr = new StreamReader(cryptoStream,true);

string textoLimpio = sr.ReadToEnd(); Console.WriteLine("Texto Limpio:{0}", textoLimpio);

return textoLimpio; }

Por ltimo el mtodo Main del programa:

class Program { static void Main(string[] args) { Console.WriteLine("Introduce el texto a encriptar:");

string message = Console.ReadLine(); TripleDESUtil crypto = new TripleDESUtil(); byte[] cifrado = crypto.Encriptar( message); string texto = crypto.DesEncriptar(cifrado); Console.ReadLine(); } }

Es importante observar que es la misma instancia de la clase TripleDESUtil quien encripta y desencripta, esto es muy importante, ya que de este modo se reutilizan las claves, definidas en las propiedades Key y IV al principio. Sin estas claves no podremos desencriptar. A continuacin mostramos el cdigo completo del ejemplo para que no queden dudas.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.IO;

namespace TripleDESEncriptor { class Program { static void Main(string[] args) {

Console.WriteLine("Introduce el texto a encriptar:"); string message = Console.ReadLine(); TripleDESUtil crypto = new TripleDESUtil(); byte[] cifrado = crypto.Encriptar( message); string texto = crypto.DesEncriptar(cifrado); Console.ReadLine(); } }

class TripleDESUtil { public byte[] IV { get; set; }

public byte[] Key { get; set; }

public string DesEncriptar(byte[] message) { TripleDES cryptoProvider = new TripleDESCryptoServiceProvider();

ICryptoTransform cryptoTransform = cryptoProvider.CreateDecryptor(Key,IV );

MemoryStream memoryStream = new MemoryStream(message);

CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Read);

StreamReader sr = new StreamReader(cryptoStream,true);

string textoLimpio = sr.ReadToEnd();

Console.WriteLine("Texto Limpio:{0}", textoLimpio); return textoLimpio; }

public byte[] Encriptar( string cadenaOrigen) { UTF8Encoding encoding = new UTF8Encoding(); byte[] message = encoding.GetBytes(cadenaOrigen);

TripleDESCryptoServiceProvider criptoProvider = new TripleDESCryptoServiceProvider();

IV = criptoProvider.IV; Key = criptoProvider.Key;

ICryptoTransform criptoTransform = criptoProvider.CreateEncryptor(Key, IV);

MemoryStream memoryStream = new MemoryStream();

CryptoStream cryptoStream = new CryptoStream(memoryStream, criptoTransform, CryptoStreamMode.Write);

cryptoStream.Write(message, 0, message.Length); // cryptoStream.Flush(); cryptoStream.FlushFinalBlock();

byte[] encriptado = memoryStream.ToArray(); string cadenaEncriptada = encoding.GetString(encriptado); Console.WriteLine("Texto encriptado:{0}",cadenaEncriptada); Console.WriteLine();

return encriptado; }

} }

Por ltimo recordar un enlace con un ejemplo para encriptar utilizando el algoritmo AES:

http://www.devjoker.com/contenidos/Articulos/432/Encriptacion-con-RijndaelEjemplo.aspx

Como encriptar cadenas y campos en SQL server 2005


SQL server 2005 trae soporte para todo tipo de encriptacin, en pero en este articulo nos centraremos en el ms rpido y sencillo, tambin es el ms inseguro, pero es infinitamente mejor que nada. Ante todo un consejo: a ms datos encriptados ms lento y complejo ser nuestro trabajo y el acceso a los datos, hay que encriptar slo lo necesario. Supongamos que tenemos una base de datos donde se almacenan todos los usuarios y sus contraseas y queremos guardar el valor de esas contraseas encriptadas, podemos usar la nueva funcin ENCRYPTBYPASSPHRASE Supongamos que la tabla tenga dos campos user y pass:

INSERT INTO USUARIOS VALUES ("Aldeamedia", ENCRYPTBYPASSPHRASE('C1trasea','MiContrasea')) GO

Si examinamos el contenido de la tabla usuarios veremos que el campo password contendr un valor similar a este: 0x02000000B351570EC53EE578CB15ED15BEDA340BFE55C44C6C2833F1 es nuestra contrasea encriptada. Para poder leerla tendremos que usar la misma contrasea que usamos para encriptar y la funcin DECRYPTBYPASSPHRASE.

SELECT

User, CONVERT(VARCHAR(300), DECRYPTBYPASSPHRASE('C1trasea',Pass)) FROM USUARIOS

Como digo hay por lo menos tres forms ms de encriptar, usando claves simetricas, asimetricas y certificados digitales, pero esta es la ms sencilla y muy eficiente siempre que mantengamos la contrasea de encriptacin bin segura. La mejor forma de usar esta encriptacin es mediante procedimientos almacenados que tomen la contrasea de encriptacin como parametro. Dudas? no os canseis de preguntar en los foros de devjoker. Pablo Gumpert Fernandez

Vous aimerez peut-être aussi