Saltar al contenido principal

 none
Error al tratar de leer certificado desde mi web RRS feed

  • Pregunta

  •  //Se comprueba si esta logado a traves de la carga con certificado digital.
            X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
            X509Certificate2 x509Cert2 = new X509Certificate2(Request.ClientCertificate.Certificate);
    
            X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
            X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
            X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(fcollection, "Selección de Certificado", "Seleccione un certificado de la siguiente lista para obtener información sobre ese certificado", X509SelectionFlag.MultiSelection);
            Console.WriteLine("Número de certificados: {0}{1}", scollection.Count, Environment.NewLine);
    
            foreach (X509Certificate2 x509 in scollection)
            {
    
                try
                {
    
                    Session["serialnumber"] = x509.SerialNumber;
                    x509.Reset();
                }
                catch (CryptographicException)
                {
                    Response.Redirect("~/Default.aspx");
                }
            }
            store.Close();

    Tengo el código anterior para cargar ciertos datos del certificado digital que seleccione, pero cuando lo hago desde el servidor me sale el siguiente error.

    
    Error de servidor en la aplicación '/'.
    La sesión actual no es interactiva.
    Descripción: Excepción no controlada al ejecutar la solicitud Web actual. Revise el seguimiento de la pila para obtener más información acerca del error y dónde se originó en el código.
    
    Detalles de la excepción: System.InvalidOperationException: La sesión actual no es interactiva.
    
    Error de código fuente:
    
    
    Línea 28:         X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
    Línea 29:         X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
    Línea 30:         X509Certificate2Collection scollection = 
    Línea 31:             X509Certificate2UI.SelectFromCollection(fcollection, "Selección de Certificado",
    Línea 32:             "Seleccione un certificado de la siguiente lista para obtener información sobre ese certificado", 
    
    Archivo de origen: D:\Proyectos clientes Gestfac\Gestion900iam_sql\bin\Debug\web\prueba.aspx.cs    Línea: 30
    
    Seguimiento de la pila:
    
    
    [InvalidOperationException: La sesión actual no es interactiva.]
       System.Security.Cryptography.CAPI.CryptUIDlgSelectCertificateW(CRYPTUI_SELECTCERTIFICATE_STRUCTW csc) +353935
       System.Security.Cryptography.X509Certificates.X509Certificate2UI.SelectFromStore(SafeCertStoreHandle safeSourceStoreHandle, String title, String message, X509SelectionFlag selectionFlags, IntPtr hwndParent) +304
       System.Security.Cryptography.X509Certificates.X509Certificate2UI.SelectFromCollectionHelper(X509Certificate2Collection certificates, String title, String message, X509SelectionFlag selectionFlag, IntPtr hwndParent) +180
       System.Security.Cryptography.X509Certificates.X509Certificate2UI.SelectFromCollection(X509Certificate2Collection certificates, String title, String message, X509SelectionFlag selectionFlag) +18
       prueba.Page_Load(Object sender, EventArgs e) in D:\Proyectos clientes Gestfac\Gestion900iam_sql\bin\Debug\web\prueba.aspx.cs:30
       System.Web.UI.Control.OnLoad(EventArgs e) +108
       System.Web.UI.Control.LoadRecursive() +90
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1607
    
    Información de versión: Versión de Microsoft .NET Framework:4.0.30319; Versión ASP.NET:4.8.3928.0

    ¿Me podeis ayudar?

    martes, 19 de noviembre de 2019 15:36

Todas las respuestas

  • El problema proviene de que estas llamando a ...UI.SellectFromCollection para que se presente una ventana interactiva en la máquina en la que se está ejecutando el código. Lógicamente eso solo vale para una aplicación de escritorio, no para una aplicación web. Imagínate que funcionase, y que cuando un usuario ejecutase la aplicación web desde su PC, de repente se abriese una ventana de selección de certificados en el servidor web, que se encuentra a miles de kilometros de distancia... y ni siquiera tiene una pantalla conectada. Lógicamente se presenta un error para indicarte que estas cosas no se pueden hacer.

    ¿Realmente quieres que el usuario seleccione uno de los certificados que están instalados en el servidor (¡no en el PC del usuario!)? Si eso es lo que quieres, tendrás que escribir tú mismo el código que presente en web una ventana de selección, no existe nada preconfigurado para hacerlo automáticamente.

    Si quieres un certificado del PC del usuario, simplemente configura la aplicación desde el IIS Manager con la opción "Requerir certificado", y el navegador presentará automáticamente una ventana para seleccionar el certificado desde el lado cliente.

    martes, 19 de noviembre de 2019 17:11
  • Muchas gracias por tu respuesta Pablo, lo que quiero es que desde un equipo cliente  entre en una web donde se pueda logar a traves de su certificado digital, teniendo previamente almacenados en el servidor web, en una base de datos el SerialNumber del certificado digital, y utilizar este campo del certificado digital como autenticador. Por tanto debe solicitarle el certificado digital del lado del cliente y que la web lea el certificado y extraiga el dato que necesito.

    • Editado Gori0056 martes, 19 de noviembre de 2019 19:29
    martes, 19 de noviembre de 2019 19:28
  • Entonces, lo que te he dicho: Marcas el sitio web en IIS como "requiere certificado" y eso hace que el navegador le presente una ventanita al usuario para que seleccione un certificado de su PC. Para que el servidor lo reconozca, hace falta que el certificado haya sido emitido por una autoridad de certificación que sea reconocida por el servidor. Si el certificado tiene lista de revocación, también hace falta que el servidor pueda acceder a la lista, aunque esto puede desactivarse si es necesario.

    Suponiendo que se supere la anterior barrera, en el servidor puedes recuperar cuál fue el certificado presentado mediante Request.ClientCertificate.Certificate. A partir de ahí puedes tomar su Thumbprint o su SerialNumber y buscarlo en tu base de datos para ver si es uno de los que tienes permitidos. No hace falta para nada en ningún momento buscar ese certificado en el Certificate Store del servidor. No solo no hace falta, sino que de hecho lo normal será que el certificado del usuario NO se encuentre ahí.

    • Marcado como respuesta Gori0056 miércoles, 20 de noviembre de 2019 6:40
    • Desmarcado como respuesta Gori0056 jueves, 21 de noviembre de 2019 15:07
    • Propuesto como respuesta Pablo RubioModerator jueves, 21 de noviembre de 2019 19:01
    martes, 19 de noviembre de 2019 20:38
  • Con la información que me proporcionaste, generé un certificado con OPENSSl para realizar prueba en el localhost. Configuré el servidor web para https en puerto 443 e importe el certificado creado, ademas de incluirlo en el sistema a traves del la consola mmc. Funciona bien como se ve en la imagenes siguiente siempre y cuando no active la opción de requerir certificado de cliente. En el siguiente enlace de Youtube esta grabado el proceso que he seguido, no se por donde continuar. https://www.youtube.com/watch?v=-aT1-TjRSHY&feature=youtu.be


    El certificado ha sido creado con OPENSSL con los siguientes parametros:

    openssl genrsa -des3 -out LlaveRSA.key 2048

    openssl req -new -key LlaveRSA.key -out Certificado.csr -config openssl.cfg -extensions v3_req

    openssl req -text -noout -in Certificado.csr

    openssl x509 -req -days 365 -in Certificado.csr -signkey LlaveRSA.key -out firmaCERTIFICADO.crt

    openssl pkcs12 -export -out certificadoiam.pfx -inkey LlaveRSA.key -in firmaCERTIFICADO.crt

    jueves, 21 de noviembre de 2019 15:35
  • Con la información que me proporcionaste, generé un certificado con OPENSSl para realizar prueba en el localhost. Configuré el servidor web para https en puerto 443 e importe el certificado creado, ademas de incluirlo en el sistema a traves del la consola mmc. Funciona bien como se ve en la imagenes siguiente siempre y cuando no active la opción de requerir certificado de cliente. En el siguiente enlace de Youtube esta grabado el proceso que he seguido, no se por donde continuar. https://www.youtube.com/watch?v=-aT1-TjRSHY&feature=youtu.be


    El certificado ha sido creado con OPENSSL con los siguientes parametros:

    openssl genrsa -des3 -out LlaveRSA.key 2048

    openssl req -new -key LlaveRSA.key -out Certificado.csr -config openssl.cfg -extensions v3_req

    openssl req -text -noout -in Certificado.csr

    openssl x509 -req -days 365 -in Certificado.csr -signkey LlaveRSA.key -out firmaCERTIFICADO.crt

    openssl pkcs12 -export -out certificadoiam.pfx -inkey LlaveRSA.key -in firmaCERTIFICADO.crt

    Detalles del emisor del Certificado


    jueves, 21 de noviembre de 2019 16:06
  • Tiene toda la pinta de que ocurre esto que te indiqué en una respuesta anterior:

    "Para que el servidor lo reconozca, hace falta que el certificado haya sido emitido por una autoridad de certificación que sea reconocida por el servidor"

    y que addemás también te advierte el propio mensaje de error de IIS donde dice "Causas más probables" (ver la última de las causas).

    Dado que es un certificado autogenerado (con OpenSSL) y que no proviene de una autoridad certificadora, no sé decirte cómo instalar el certificado de la autoridad certificadora. Sé que se puede hacer, o por lo menos se puede cuando lo generas con MakeCert, me imagino que OpenSsl tendrá alguna opción parecida. Pero no sé cómo se hace, tendrás que hacer una búsqueda para encontrar algún documento que lo describa.

    jueves, 21 de noviembre de 2019 16:39
  • ¿Cual sería la forma de hacerlo con MakeCert, quiero decir, el comando a utilizar?, tambien puedo generarlo con MakeCert, pero no conozco los comandos.

    jueves, 21 de noviembre de 2019 18:33
  • Yo tampoco conozco los comandos. Lo que hice la vez que me hizo falta es que lo puse en un buscador y entre los varios enlaces devueltos encontré uno que me llevó a un artículo donde venían todas las instrucciones paso a paso. Simplemente las copié y me funcionó todo. Pero no las recuerdo de memoria.

    Por ejemplo, en este artículo: https://medium.com/the-new-control-plane/generating-self-signed-certificates-on-windows-7812a600c2d8 vienen varias formas de generar un certificado auto-firmado, incluyendo MakeCert, OpenSsl y PowerShell.

    Para que Windows confíe en la "autoridad" que emitió ese certificado auto-firmado, simplemente impórtalo en el almacén de certificados y cuando te pregunte que en qué carpeta lo quieres importar dile que en “Trusted Root Certification Authorities”. En principio con eso debería bastar para que se reconozca desde ese equipo. Esto lo tienes que hacer en el servidor. En cambio en el puesto cliente que tiene que enviar ese certificado al servidor, hay que importarlo en "Personal".

    jueves, 21 de noviembre de 2019 22:34
  • He creado los certificados tanto con MakeCert con los siguientes instrucciones, y sigue sin solicitarme el certificado del cliente dando siempre el mismo error si esta activo "Requerir certificado cliente", ya no se por donde tirar...

    makecert -n "CN=root signing authority" -cy authority -r -sv root.pvk root.cer

    makecert -r -pe -n "CN=localhost" -b 01/01/2012 -e 01/01/2020 -sky exchange localhost.cer -sv localhost.pvk
    makecert -ic root.cer -iv root.pvk -n "CN=localhost" -sv localhost.pvk -pe -sky exchange localhost.cer
    pvk2pfx.exe -pvk localhost.pvk -spc localhost.cer -pfx localhost.pfx
    sábado, 23 de noviembre de 2019 13:02
  • He creado los certificados

    Pero, aparte de crearlo, ¿hiciste la instalación bajo “Trusted Root Certification Authorities”?

    sábado, 23 de noviembre de 2019 13:51
  • sii

    sábado, 23 de noviembre de 2019 16:49