none
validacion de contraseñas RRS feed

  • Pregunta

  • buen dia para todos

     

    tengo el siguiente caso: estoy haciendo un proyecto mixto entre windows y web, utilice la seguridad ASP.net, y cree los usuarios y sus contraseñas, ahora tengo que hacer un form de logeo  para la aplicacion windows, y quiero manejar la validacion manualmente. quisiera saber como convertir la cadena (password) que ingrese el usuario al codigo HASH que utiliza asp para guardar las contraseñas y asi poeder comparar la que ingresa el usuario con la existente en mi base de datos? o como me recomendarian comparar la contraseña que ingresa el usuario con la existente en la bd

     

    muchas gracias por su ayuda y colaboracion

     

    Jose Vicente Silva Rivera

    martes, 29 de enero de 2008 15:44

Respuestas

  •  

    OK, estuve haciendo algunas pruebas y creo que el proceso más simple para lograrlo es el siguiente. Sólo necesitarás saber cuál es el membership provider utilizado en la aplicación web. No vamos a encriptar el password y compararlo sino dejar la validación completa al framework (lo cuál va a resultar muchísmo más simple).

     

    1) lo primero es agregar una referencia a System.Web.dll y a System.Configuration (la segunda es requerida por la primera). Esto te va a permitir acceder a las clases que utiliza el Wizard y los controles de login de ASP .NET.

     

    2) creá un formulario de prueba, agreale un botón y reemplazá el contenido del archivo .cs por este

     

    Code Snippet

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Data;

    using System.Drawing;

    using System.Text;

    using System.Windows.Forms;

     

    ////////////////////////////////////

    // yo agregué estas dos sentencias

    using System.Web.Security;

    using System.Configuration;

    ///////////////////////////////////

     

    namespace WindowsApplication1

    {

       public partial class Form1 : Form

       {

          public Form1()

          {

             InitializeComponent();

          }

          private void button1_Click(object sender, EventArgs e)

          {

          // las siguientes dos líneas de código van a validar las credenciales.

          bool isMember = Membership.ValidateUser("carlos", "!234qwer");

         

          MessageBox.Show(string.Format("Credentials are {0}valid", (isMember)? string.Empty:"NOT ")); // esto no está muy bien, pero cumple con lo que se necesita para una prueba

          }

       }

    }

     

     

    2) Ahora bien, para que la validación funcione debemos debemos configurar la clase Membership. Yo lo hice del siguiente modo, pero es posible que el modo en que vos hayas creado y configurado tu aplicación web sea distinto. De todos modos creo que viendo mi ejemplo vas a poder darte una idea.

     

    del Web.config de la aplicación tomé los nodos correspondientes a la conection string que permite el acceso al sql donde está la base de ASP .NET y la configuración del Membership Provider. Esa info la pegué en un App.config:

     

    Code Snippet

    <configuration>

      <connectionStrings>

        <add name="SqlServices" connectionString="Data Source=localhost\SQLEXPRESS2005;Integrated Security=SSPI;Initial Catalog=aspnetdb;"/>

      </connectionStrings>

      <system.web>

        <membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">

          <providers>

            <add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="SqlServices" applicationName="MyApplication" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" passwordAttemptWindow="10"/>

          </providers>

        </membership>

      </system.web>

    </configuration>

     

     

    Eso es todo, si presionas el botón en el formuario debería validar tus credenciales contra la base de datos de ASP.NET

     

    Aunque parezca extraño ver un nodo llamado system.web en una aplicación windows, este es necesario para que la clase Membership pueda obtener la configuración correcta. Si utilizaste otra metodología para configurar tu aplicación web que no sea a través del Web.config, posteá la info y vemos cómo adaptarlo.

     

     

    martes, 29 de enero de 2008 19:29
  •  

    José,

     

    has evaluado alguna alternativa de arquitectura de componentes como la siguiente ?

     

    en primer lugar tendrías la aplicación windows. esta aplicación podría pedir las credenciales de usuario (user/pass). esa aplicación encryptaría estos dos valores y los pasaría a un webservice.

    este webservice (que no es otra cosa que una aplicación web) se encargaría de desencriptar las credenciales e invocar el método del Membership para validarlas. 

     

    de este modo, del lado del cliente sólo necesitas las clases necesarias para encriptar las credenciales, el proxy del webservice y un formulario para recoger el ingreso del usuario. del lado del servidor (podría ser en el mismo en el que corre la aplicación web) necesitarías el webservice que a su vez incluiría las clases para desencriptar las credenciales y las clase para validar esas credenciales.

    miércoles, 30 de enero de 2008 23:57

Todas las respuestas

  • te hago una consulta: cómo llegaron las passwords de los usuarios encriptadas a la base de datos ?

     

    si estás utilizando el CreateUserWizard de .NET, entonces tienes que verificar la configuración del Membership Provider y precisar qué método de encriptación estás utilzando. Una vez que tienes ese dato, puedes utilizar el mismo método para encriptar el password que ingresa el usuario y compararlo con la versió que tienes en la base de datos.

     

    martes, 29 de enero de 2008 16:30
  • si estoy utilizando el CreateUserWizard de .net y el metodo en el provider que utilice fue passwordFormat="Hashed"; te agradeceria si me das un ejemplo de como usar el metodo para encriptar el password insertado por el usuario

     

    gracias

     

    Jose Vicente Silva Rivera

    martes, 29 de enero de 2008 16:44
  •  

    OK, estuve haciendo algunas pruebas y creo que el proceso más simple para lograrlo es el siguiente. Sólo necesitarás saber cuál es el membership provider utilizado en la aplicación web. No vamos a encriptar el password y compararlo sino dejar la validación completa al framework (lo cuál va a resultar muchísmo más simple).

     

    1) lo primero es agregar una referencia a System.Web.dll y a System.Configuration (la segunda es requerida por la primera). Esto te va a permitir acceder a las clases que utiliza el Wizard y los controles de login de ASP .NET.

     

    2) creá un formulario de prueba, agreale un botón y reemplazá el contenido del archivo .cs por este

     

    Code Snippet

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Data;

    using System.Drawing;

    using System.Text;

    using System.Windows.Forms;

     

    ////////////////////////////////////

    // yo agregué estas dos sentencias

    using System.Web.Security;

    using System.Configuration;

    ///////////////////////////////////

     

    namespace WindowsApplication1

    {

       public partial class Form1 : Form

       {

          public Form1()

          {

             InitializeComponent();

          }

          private void button1_Click(object sender, EventArgs e)

          {

          // las siguientes dos líneas de código van a validar las credenciales.

          bool isMember = Membership.ValidateUser("carlos", "!234qwer");

         

          MessageBox.Show(string.Format("Credentials are {0}valid", (isMember)? string.Empty:"NOT ")); // esto no está muy bien, pero cumple con lo que se necesita para una prueba

          }

       }

    }

     

     

    2) Ahora bien, para que la validación funcione debemos debemos configurar la clase Membership. Yo lo hice del siguiente modo, pero es posible que el modo en que vos hayas creado y configurado tu aplicación web sea distinto. De todos modos creo que viendo mi ejemplo vas a poder darte una idea.

     

    del Web.config de la aplicación tomé los nodos correspondientes a la conection string que permite el acceso al sql donde está la base de ASP .NET y la configuración del Membership Provider. Esa info la pegué en un App.config:

     

    Code Snippet

    <configuration>

      <connectionStrings>

        <add name="SqlServices" connectionString="Data Source=localhost\SQLEXPRESS2005;Integrated Security=SSPI;Initial Catalog=aspnetdb;"/>

      </connectionStrings>

      <system.web>

        <membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">

          <providers>

            <add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="SqlServices" applicationName="MyApplication" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" passwordAttemptWindow="10"/>

          </providers>

        </membership>

      </system.web>

    </configuration>

     

     

    Eso es todo, si presionas el botón en el formuario debería validar tus credenciales contra la base de datos de ASP.NET

     

    Aunque parezca extraño ver un nodo llamado system.web en una aplicación windows, este es necesario para que la clase Membership pueda obtener la configuración correcta. Si utilizaste otra metodología para configurar tu aplicación web que no sea a través del Web.config, posteá la info y vemos cómo adaptarlo.

     

     

    martes, 29 de enero de 2008 19:29
  • hola

     

    ok si me funciono, es decir no me genero errores de compilacion ni nada, pero no reconoce ninguno de los usuarios que tengo creados, no se si es que se deben crear los usuarios desde la misma estancia o alo asi.

     

    gracias

     

    bikent

     

    martes, 29 de enero de 2008 21:10
  • hola que pena con la respuesta anterior, si funciona perfectamente, ya lo probe en visualbasic y funciona igual, solo hay que tener cuidado con el id de la aplicacion que se guarda en la base de datos, debe ser el mismo de la aplicacion, por lo demas funciona correctamente.

     

    ahora bien, como nueva condicion me proponen, que no utilice la conectionstring para llegar a los datos sino por un web service, para eso creo que necesito saber como encripta el asp y tratar de desencriptarlo y compararlo con lo que ingresa el usuario, o encriptar lo que ingresa el usuario y compararlo con la base de datos, si sabes como te agradezco tu ayuda.

     

    jose vicente

    martes, 29 de enero de 2008 21:50
  • perdón por la demora

     

    bueno, en primer lugar el webservice. creo que no va a ser mayor problema implementar la solución con la que ensayamos en la windows application en un webservice. supongo que hasta ahí vamos bien.

     

    en segundo lugar, la encriptación. el siguiente es un ejemplo sobre como encriptar/desencriptar un texto. sólo tienes que crear una aplicació de consola y pegar el siguiente código:

     

    Code Snippet

    class Program

    {

    static void Main(string[] args)

    {

    Console.WriteLine("give me a word to encrypt:");

    string clearTXT = Console.ReadLine();

    System.Security.Cryptography.RSACryptoServiceProvider csp = new System.Security.Cryptography.RSACryptoServiceProvider();

    byte[] bytes = System.Text.Encoding.UTF8.GetBytes(clearTXT);

    byte[] encrypted = csp.Encrypt(bytes, true);

    Console.WriteLine("encrypted text is:");

    Console.WriteLine(System.Text.Encoding.UTF8.GetString(encrypted, 0, encrypted.Length));

    byte[] unencrypted = csp.Decrypt(encrypted, true);

    Console.WriteLine("unencrypted text is:");

    Console.WriteLine(System.Text.Encoding.UTF8.GetString(unencrypted, 0, unencrypted.Length));

    Console.ReadKey();

    }

    }

     

     

    simplemente te estoy dando un ejemplo de cómo hacerlo. si investigas un poco vas a encontrar que hay otros cryptoservicesprocviders y distintas maneras de configurarlos. pero esto es suficientemente seguro y creo que va a servir bien a tus fines.

     

    esperamos tus comentarios...

    miércoles, 30 de enero de 2008 17:01
  • hola

     

    el problema con la solucion que implementamos es que no se quiere que la aplicacion windows toque directamente la base de datos, es decir que no puede ir la connection string en el appconfig del aplicativo.

     

    para evitar esto implemente una libreria de clases y ahi volvi a implementar la solucion que me enviaste, agregando un appconfig en la biblioteca de librerias y pegando ahi el provider y la conectionstring.

     

    el problema es que cuando invoco la libreria desde mi aplicacion, esta busca el appconfig de la aplicacion y no el propio, y obviamente no funciona pues el aplicativo windows no tiene el appconfig definido,

     

    si llega a funcionar el objetivo final es el siguiente: del aplicativo windows se toman el nombre de usuario y la contraseña, se envian a travez de un webservce a una clase o libreria de clase que se encargaria de verificar la existencia del usuario y retornaria la confirmacion a la aplicacion.

     

    es por politica que se tiene que el aplicativo windows no toque directamente la capa de datos.

     

    muchas gracias por su colaboracion

     

    att

     

    Jose vicente silva rivera

    miércoles, 30 de enero de 2008 19:41
  •  

    José,

     

    has evaluado alguna alternativa de arquitectura de componentes como la siguiente ?

     

    en primer lugar tendrías la aplicación windows. esta aplicación podría pedir las credenciales de usuario (user/pass). esa aplicación encryptaría estos dos valores y los pasaría a un webservice.

    este webservice (que no es otra cosa que una aplicación web) se encargaría de desencriptar las credenciales e invocar el método del Membership para validarlas. 

     

    de este modo, del lado del cliente sólo necesitas las clases necesarias para encriptar las credenciales, el proxy del webservice y un formulario para recoger el ingreso del usuario. del lado del servidor (podría ser en el mismo en el que corre la aplicación web) necesitarías el webservice que a su vez incluiría las clases para desencriptar las credenciales y las clase para validar esas credenciales.

    miércoles, 30 de enero de 2008 23:57
  • buen dia

     

     

    tienes toda la razón esa idea me anduvo rondando la cabeza desde ayer en la tarde, y pues lo que utilize fue agregar un web service, a este le agregue (aunque creo que no era del todo necesario) las referencias del system.web y . configuration, luego en el mismo webservice importe las librerias y cree una funcion que hace lo siguiente

     

    Imports System.web.Security

    Imports System.Configuration

     

     

    <WebMethod()> _

    Public Function Validacion(ByVal NomUsuario As String, ByVal Contraseña As String) As Boolean

    Dim IsMember As Boolean = Membership.ValidateUser(NomUsuario, Contraseña)

    Return IsMember

    End Function

     

     

    y en la aplicacion windows lo unico que hago es invocar el webservice crearle la instancia y utilizar esta funcion pasandole directamente los parametros que escribe el usuario.... la funcion validate user se encarga de encriptar y verificar. y funcionó correctamente

     

    igualmente pues muchisimas gracias por toda tu colaboracion estamos pendientes para los nuevos retos

     

    Jose Vicente Silva Rivera

    jueves, 31 de enero de 2008 16:32