DNI Electrónico Helper

Siempre me ha parecido muy mala la implantación del DNI electrónico: hay muchas páginas que sólo lo soportan en navegadores específicos, otras necesitan lectores específicos y otras directamente no lo soportan aunque aparentemente sí que lo hagan.

En cualquier caso, incluso las que funcionan bien, te exigen escribir la clave unas cuantas veces durante el proceso: para acceder al almacén de certificados, selecionarlo, utilizarlo… Al final si tienes una clave segura resulta muy incómodo utilizarlo.

Pensando en esta comodidad y en poder hacer aplicaciones de integración con bancos automatizadas he desarrollado un pequeño programa que al ser ejecutado detecta todas las interacciones con el lector de DNIs e introduce la contraseña sin necesidad de intervención del usuario. Aunque no os interese la funcionalidad es interesante ver cómo se detecta una ventana y se envían caracteres a otra aplicación.

La presentación es mejorable :-P, of course, pero funciona! La clave se guarda en AppData encriptada. La opción de «seleccionar certificado» hace que tambien se seleccione automáticamente el certificado, útil si sólo tienes uno en tu equipo. El segundo check muestra un aviso en el área de notificación cada vez que se detecta la ventana y espera un segundo antes de actuar automáticamente.

Veamos un poco de código:

                 //Detección de la Ventana de introducción clave DNI electrónico y envío de caractéres
                dniApp = FindWindow(null, «DNI electrónico»);
                if (dniApp.ToInt32() > 0)
                {
                    if (chkNotificaciones.Checked)
                    {
                        notify.ShowBalloonTip(500, «DNI Electrónico Helper», «Peticion de clave DNI», ToolTipIcon.None);
                        System.Threading.Thread.Sleep(1000);
                    }
                    SetForegroundWindow(dniApp);
                    SendKeys.SendWait(Crypto.DecryptStringAES(Properties.Settings.Default.Clave, claveEncriptacion));
                    SendKeys.SendWait(«{ENTER}»);
                }

        //Imports de DLLs
        [DllImport(«USER32.DLL», CharSet = CharSet.Unicode)]
        public static extern IntPtr FindWindow(string lpClassName,
            string lpWindowName);
       
        // Activate an application window.
        [DllImport(«USER32.DLL»)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
        #endregion

Adjunto el código y el ejecutable para probarlo, espero que os sea útil!