Introducción al desarrollo seguro de aplicaciones de Windows

Este artículo introductorio ayuda a los arquitectos y desarrolladores de aplicaciones a comprender mejor las diversas capacidades de la plataforma Windows 10 que aceleran la creación de aplicaciones seguras de la Plataforma Universal de Windows (UWP). Detalla cómo utilizar las características de seguridad de Windows disponibles en cada una de las siguientes etapas: autenticación, datos en tránsito y datos en reposo. Puede encontrar información más detallada sobre cada tema revisando los recursos adicionales incluidos en cada capítulo.

1 Introducción

Desarrollar una aplicación segura puede ser todo un reto. En el vertiginoso mundo actual de aplicaciones móviles, sociales, en la nube y empresariales complejas, los clientes esperan que las aplicaciones estén disponibles y se actualicen más rápido que nunca. También utilizan muchos tipos de dispositivos, lo que aumenta aún más la complejidad de crear experiencias de aplicaciones. Si crea para la plataforma universal de Windows 10 y Windows 11 (UWP), podría incluir la lista tradicional de ordenadores de sobremesa, portátiles, tabletas y dispositivos móviles, además de una lista creciente de nuevos dispositivos que abarcan el Internet de las cosas, Xbox One, Microsoft Surface Hub y HoloLens. Como desarrollador, debes asegurarte de que tus aplicaciones se comunican y almacenan datos de forma segura, en todas las plataformas o dispositivos implicados.

Estas son algunas de las ventajas de utilizar las características de seguridad de Windows 10 y Windows 11.

  • Dispondrá de seguridad estandarizada en todos los dispositivos compatibles con Windows 10 y Windows 11, mediante el uso de API coherentes para componentes y tecnologías de seguridad.
  • Escribe, prueba y mantiene menos código que si implementara código personalizado para cubrir estos escenarios de seguridad.
  • Sus aplicaciones son más estables y seguras porque utiliza el sistema operativo para controlar cómo accede la aplicación a sus recursos y a los recursos locales o remotos del sistema.

Durante la autenticación, se valida la identidad de un usuario que solicita acceso a un servicio concreto. Windows Hello es el componente de Windows 10 y Windows 11 que ayuda a crear un mecanismo de autenticación más seguro en las aplicaciones de Windows. Con él, puede utilizar un número de identificación personal (PIN) o datos biométricos como las huellas dactilares, la cara o el iris del usuario para implementar la autenticación multifactor en sus aplicaciones.

Los datos en tránsito se refieren a la conexión y a los mensajes transferidos a través de ella.. Un ejemplo es la recuperación de datos de un servidor remoto mediante servicios web. El uso de Secure Sockets Layer (SSL) y Secure Hypertext Transfer Protocol (HTTPS) garantiza la seguridad de la conexión. Evitar que los intermediarios accedan a estos mensajes o que aplicaciones no autorizadas se comuniquen con los servicios web es clave para proteger los datos en tránsito.

Por último, los datos en reposo se refieren a los datos que residen en la memoria o en medios de almacenamiento. Windows 10 y Windows 11 tienen un modelo de aplicación que impide el acceso no autorizado a los datos entre aplicaciones, y ofrece API de cifrado para proteger aún más los datos en el dispositivo. Se puede utilizar una función llamada Credential Locker para almacenar de forma segura las credenciales de usuario en el dispositivo, con el sistema operativo impidiendo que otras apps accedan a ellas.

2 Factores de autenticación

Para proteger los datos, la persona que solicita acceso a ellos debe estar identificada y autorizada para acceder a los recursos de datos que solicita. El proceso de identificar a un usuario se denomina autenticación, y el de determinar los privilegios de acceso a un recurso, autorización. Se trata de operaciones estrechamente relacionadas, y para el usuario pueden resultar indistinguibles. Pueden ser operaciones relativamente sencillas o complejas, dependiendo de muchos factores: por ejemplo, si los datos residen en un servidor o están distribuidos en muchos sistemas. El servidor que proporciona los servicios de autenticación y autorización se denomina proveedor de identidad.

Para autenticarse en un determinado servicio o aplicación, el usuario utiliza credenciales compuestas por algo que sabe, algo que tiene o algo que es. Cada uno de estos elementos se denomina factor de autenticación.

  • Algo que el usuario sabe suele ser una contraseña, pero también puede ser un número de identificación personal (PIN) o un par "secreto" de pregunta-respuesta.
  • Algo que tiene el usuario tiene suele ser un dispositivo de memoria de hardware, como una memoria USB, que contiene los datos de autenticación exclusivos del usuario.
  • Algo que el usuario suele abarcar son sus huellas dactilares, pero cada vez son más populares factores como el habla del usuario, sus características faciales, oculares (ojos) o sus patrones de comportamiento. Cuando se almacenan como datos, estas medidas se denominan biométricas.

Una contraseña creada por el usuario es un factor de autenticación en sí mismo, pero a menudo no es suficiente; cualquiera que conozca la contraseña puede suplantar al usuario que la posee. Una tarjeta inteligente puede proporcionar un mayor nivel de seguridad, pero podría ser robado, perdido o mal colocado. Un sistema que pueda autenticar a un usuario mediante su huella dactilar o un escáner ocular podría proporcionar el nivel de seguridad más alto y conveniente, pero requiere un hardware caro y especializado (por ejemplo, una cámara Intel RealSense para el reconocimiento facial) que podría no estar disponible para todos los usuarios.

El diseño del método de autenticación utilizado por un sistema es un aspecto complejo e importante de la seguridad de los datos. En general, cuanto mayor sea el número de factores que se utilicen en la autenticación, más seguro será el sistema. Al mismo tiempo, la autenticación debe poder utilizarse. Un usuario suele iniciar sesión muchas veces al día, por lo que el proceso debe ser rápido. La elección del tipo de autenticación es un compromiso entre seguridad y facilidad de uso; la autenticación de factor único es la menos segura y la más fácil de usar, y la autenticación multifactor es más segura, pero más compleja a medida que se añaden más factores.

2.1 Autenticación de factor único

Esta forma de autenticación se basa en una única credencial de usuario. Suele ser una contraseña, pero también puede ser un número de identificación personal (PIN).

Este es el proceso de la autenticación de factor único.

  • El usuario proporciona su nombre de usuario y contraseña al proveedor de identidad. El proveedor de identidad es el proceso del servidor que verifica la identidad del usuario.
  • El proveedor de identidad comprueba si el nombre de usuario y la contraseña coinciden con los almacenados en el sistema. En la mayoría de los casos, la contraseña se cifrará, proporcionando seguridad adicional para que otros no puedan leerla.
  • El proveedor de identidades devuelve un estado de autenticación que indica si la autenticación se ha realizado correctamente.
  • En caso afirmativo, comienza el intercambio de datos. En caso contrario, el usuario debe volver a autenticarse.

single-factor authentication

Hoy en día, este método de autenticación es el más utilizado en todos los servicios. También es la forma de autenticación menos segura cuando se utiliza como único medio de autenticación. Los requisitos de complejidad de la contraseña, las "preguntas secretas" y los cambios periódicos de contraseña pueden hacer que el uso de contraseñas sea más seguro, pero suponen una mayor carga para los usuarios y no son un elemento disuasorio eficaz contra los piratas informáticos.

El reto de las contraseñas es que es más fácil adivinarlas con éxito que los sistemas que tienen más de un factor. Si roban una base de datos con cuentas de usuario y contraseñas cifradas de una pequeña tienda web, pueden utilizar las contraseñas usadas en otros sitios web. Los usuarios tienden a reutilizar las cuentas todo el tiempo, porque las contraseñas complejas son difíciles de recordar. Para un departamento informático, la gestión de contraseñas también conlleva la complejidad de tener que ofrecer mecanismos de restablecimiento, exigir actualizaciones frecuentes de las contraseñas y almacenarlas de forma segura.

A pesar de todas sus desventajas, la autenticación de factor único da al usuario el control de la credencial. Ellos la crean y la modifican, y solo se necesita un teclado para el proceso de autenticación. Este es el principal aspecto que distingue la autenticación de factor único de la de múltiples factores.

2.1.1 Agente de autenticación web

Como ya se ha comentado, uno de los retos de la autenticación de contraseñas para un departamento de TI es la sobrecarga añadida de gestionar la base de nombres de usuario/contraseñas, los mecanismos de restablecimiento, etc. Una opción cada vez más popular es confiar en proveedores de identidad de terceros que ofrecen autenticación a través de OAuth, un estándar abierto para la autenticación.

Utilizando OAuth, los departamentos de TI pueden "externalizar" de forma efectiva la complejidad de mantener una base de datos con nombres de usuario y contraseñas, la funcionalidad de restablecimiento de contraseñas, etc. a un proveedor de identidad externo como Facebook, X o Microsoft.

Los usuarios tienen un control total sobre su identidad en estas plataformas, pero las aplicaciones pueden solicitar un token al proveedor, después de que el usuario se autentique y con su consentimiento, que se puede utilizar para autorizar a los usuarios autenticados.

El agente de autenticación web de Windows 10 y Windows 11 proporciona un conjunto de API e infraestructura para que las aplicaciones utilicen protocolos de autenticación y autorización como OAuth y OpenID. Las aplicaciones pueden iniciar operaciones de autenticación a través de la API WebAuthenticationBroker, lo que resulta en la devolución de un WebAuthenticationResult. En la siguiente figura se ilustra el flujo de comunicación.

wab workflow

La aplicación actúa como broker, iniciando la autenticación con el proveedor de identidad a través de una WebView en la aplicación. Cuando el proveedor de identidad ha autenticado al usuario, devuelve un token a la aplicación que puede utilizarse para solicitar información sobre el usuario al proveedor de identidad. Como medida de seguridad, la aplicación debe estar registrada con el proveedor de identidad antes de que pueda intermediar en los procesos de autenticación con el proveedor de identidad. Estos pasos de registro difieren para cada proveedor.

Este es el flujo de trabajo general para llamar a la API WebAuthenticationBroker para comunicarse con el proveedor.

  • Construir las cadenas de solicitud que se enviarán al proveedor de identidad. El número de cadenas y la información que contiene cada una es diferente para cada servicio web, pero normalmente incluye dos cadenas URI que contienen cada una una URL: una a la que se envía la solicitud de autenticación y otra a la que se redirige al usuario una vez completada la autorización.
  • Llame a WebAuthenticationBroker.AuthenticateAsync, pasando las cadenas de solicitud, y espere la respuesta del proveedor de identidad.
  • Llame a WebAuthenticationResult.ResponseStatus para obtener el estado cuando se reciba la respuesta.
  • Si la comunicación tiene éxito, procesa la cadena de respuesta devuelta por el proveedor de identidad. Si no tiene éxito, procese el error.

Si la comunicación tiene éxito, procesa la cadena de respuesta devuelta por el proveedor de identidad. Si no tiene éxito, procese el error.

A continuación se muestra un ejemplo de código C# para este proceso. Para obtener información y un recorrido detallado, consulte WebAuthenticationBroker. Para obtener un ejemplo de código completo, consulte el ejemplo WebAuthenticationBroker en GitHub.

string startURL = "https://<providerendpoint>?client_id=<clientid>";
string endURL = "http://<AppEndPoint>";

var startURI = new System.Uri(startURL);
var endURI = new System.Uri(endURL);

try
{
    WebAuthenticationResult webAuthenticationResult = 
        await WebAuthenticationBroker.AuthenticateAsync( 
            WebAuthenticationOptions.None, startURI, endURI);

    switch (webAuthenticationResult.ResponseStatus)
    {
        case WebAuthenticationStatus.Success:
            // Successful authentication. 
            break;
        case WebAuthenticationStatus.ErrorHttp:
            // HTTP error. 
            break;
        default:
            // Other error.
        break;
    }
}
catch (Exception ex)
{
    // Authentication failed. Handle parameter, SSL/TLS, and
    // Network Unavailable errors here. 
}

2.2 Autenticación multifactor

La autenticación multifactor utiliza más de un factor de autenticación. Normalmente, "algo que sabes", como una contraseña, se combina con "algo que tienes", que puede ser un teléfono móvil o una tarjeta inteligente. Aunque un atacante descubra la contraseña del usuario, la cuenta sigue siendo inaccesible sin el dispositivo o la tarjeta. Y si solo se compromete el dispositivo o la tarjeta, al atacante no le sirve de nada sin la contraseña. La autenticación multifactor es por tanto más segura, pero también más compleja, que la autenticación de un solo factor.

Los servicios que utilizan la autenticación multifactor suelen dar al usuario la opción de elegir cómo recibir la segunda credencial. Un ejemplo de este tipo de autenticación es un proceso comúnmente utilizado en el que se envía un código de verificación al teléfono móvil del usuario mediante SMS.

  • El usuario proporciona su nombre de usuario y contraseña al proveedor de identidad.
  • El proveedor de identidad verifica el nombre de usuario y la contraseña como en la autorización de factor único, y luego busca el número de teléfono móvil del usuario almacenado en el sistema.
  • El servidor envía un mensaje SMS con un código de verificación generado al teléfono móvil del usuario.
  • El usuario proporciona el código de verificación al proveedor de identidad; a través de un formulario presentado al usuario.
  • El proveedor de identidad devuelve un estado de autenticación que indica si la autenticación de ambas credenciales se ha realizado correctamente.
  • En caso afirmativo, comienza el intercambio de datos. En caso contrario, el usuario debe volver a autenticarse.

two-factor authentication

Como puedes ver, este proceso también difiere de la autenticación de factor único en que la segunda credencial de usuario se envía al usuario en lugar de ser creada o proporcionada por el usuario. Por lo tanto, el usuario no tiene el control total de las credenciales necesarias. Esto también se aplica cuando se utiliza una tarjeta inteligente como segunda credencial: la organización se encarga de crearla y proporcionársela al usuario.

2.2.1 Azure Active Directory

Azure Active Directory (Azure AD) es un servicio de gestión de identidad y acceso basado en la nube que puede servir como proveedor de identidad en la autenticación de factor único o multifactor. La autenticación Azure AD puede utilizarse con o sin código de verificación.

Aunque Azure AD también puede implementar la autenticación de factor único, las empresas suelen requerir la mayor seguridad de la autenticación multifactor. En una configuración de autenticación multifactor, un usuario que se autentica con una cuenta de Azure AD tiene la opción de que se le envíe un código de verificación en forma de mensaje SMS a su teléfono móvil o a la aplicación móvil Azure Authenticator.

Además, Azure AD puede utilizarse como proveedor de OAuth, proporcionando al usuario estándar un mecanismo de autenticación y autorización para aplicaciones en varias plataformas. Para obtener más información, consulte Azure Active Directory y Autenticación multifactor en Azure.

2.4 Windows Hello

En Windows 10 y Windows 11, el sistema operativo incorpora un práctico mecanismo de autenticación multifactor. Windows Hello es el nuevo sistema de inicio de sesión biométrico integrado en Windows 10 y Windows 11. Al estar integrado directamente en el sistema operativo, Windows Hello permite la identificación facial o dactilar para desbloquear los dispositivos de los usuarios. El almacén seguro de credenciales de Windows protege los datos biométricos del dispositivo.

Windows Hello proporciona una forma sólida para que un dispositivo reconozca a un usuario individual, lo que aborda la primera parte de la ruta entre un usuario y un servicio o elemento de datos solicitado. Una vez que el dispositivo ha reconocido al usuario, aún debe autenticarlo antes de determinar si le concede acceso a un recurso solicitado. Windows Hello también proporciona una sólida autenticación de dos factores (2FA) que está totalmente integrada en Windows y sustituye las contraseñas reutilizables por la combinación de un dispositivo específico y un gesto biométrico o PIN. El PIN es especificado por el usuario como parte del registro de su cuenta Microsoft.

Sin embargo, Windows Hello no es solo un sustituto de los sistemas 2FA tradicionales. Es conceptualmente similar a las tarjetas inteligentes: la autenticación se realiza utilizando primitivas criptográficas en lugar de comparaciones de cadenas, y el material clave del usuario está seguro dentro de un hardware a prueba de manipulaciones. Microsoft Hello tampoco requiere los componentes de infraestructura adicionales necesarios para la implantación de tarjetas inteligentes. En concreto, no necesita una infraestructura de clave pública (PKI) para gestionar certificados, si no dispone de una actualmente. Windows Hello combina las principales ventajas de las tarjetas inteligentes (flexibilidad de implementación para las tarjetas inteligentes virtuales y seguridad sólida para las tarjetas inteligentes físicas) sin ninguno de sus inconvenientes.

Un dispositivo debe estar registrado en Windows Hello antes de que los usuarios puedan autenticarse con él. Windows Hello utiliza cifrado asimétrico (clave pública/privada) en el que una parte utiliza una clave pública para cifrar los datos que la otra parte puede descifrar utilizando una clave privada. En el caso de Windows Hello, se crea un conjunto de pares de claves pública/privada y se escriben las claves privadas en el chip Trusted Platform Module (TPM) del dispositivo. Una vez registrado un dispositivo, las aplicaciones UWP pueden llamar a las API del sistema para recuperar la clave pública del usuario, que puede utilizarse para registrarlo en el servidor.

El flujo de trabajo de registro de una app puede ser similar al siguiente:

windows hello registration

La información de registro que recopiles puede incluir mucha más información de identificación que en este sencillo escenario. Por ejemplo, si su aplicación accede a un servicio seguro, como uno bancario, tendrá que pedir una prueba de identidad y otras cosas como parte del proceso de registro. Una vez cumplidas todas las condiciones, la clave pública de este usuario se almacenará en el back-end y se utilizará para validar la próxima vez que el usuario utilice el servicio.

Para más información sobre Windows Hello, consulte la guía de Windows Hello y la guía para desarrolladores de Windows Hello.

3 Métodos de seguridad de datos en tránsito

Los métodos de seguridad de datos en tránsito se aplican a los datos en tránsito entre dispositivos conectados a una red. Los datos pueden transferirse entre sistemas en el entorno de alta seguridad de una intranet corporativa privada, o entre un cliente y un servicio web en el entorno no seguro de la web. Las apps de Windows 10 y Windows 11 soportan estándares como SSL a través de sus APIs de red, y trabajan con tecnologías como Azure API Management con las que los desarrolladores pueden garantizar el nivel de seguridad adecuado para sus apps.

3.1 Autenticación de sistemas remotos

Existen dos escenarios generales en los que se produce la comunicación con un sistema informático remoto.

  • Un servidor local autentica a un usuario a través de una conexión directa. Por ejemplo, cuando el servidor y el cliente están en una intranet corporativa.
  • Se comunica con un servicio web a través de Internet.

Los requisitos de seguridad para la comunicación de servicios web son mayores que los de los escenarios de conexión directa, ya que los datos ya no forman parte únicamente de una red segura y la probabilidad de que atacantes malintencionados busquen interceptar datos también es mayor. Dado que varios tipos de dispositivos accederán al servicio, es probable que se construyan como servicios RESTful, a diferencia de WCF, por ejemplo, lo que significa que la autenticación y autorización al servicio también introduce nuevos retos. Hablaremos de dos requisitos para la comunicación segura de sistemas remotos.

El primero es la confidencialidad de los mensajes: La información transmitida entre el cliente y los servicios web (por ejemplo, la identidad del usuario y otros datos personales) no debe poder ser leída por terceros durante el tránsito. Esto se consigue normalmente cifrando la conexión a través de la cual se envían los mensajes y cifrando el propio mensaje. En el cifrado de clave privada/pública, la clave pública está al alcance de cualquiera y se utiliza para cifrar los mensajes que se envían a un receptor concreto. La clave privada solo la tiene el receptor y se utiliza para descifrar el mensaje.

El segundo requisito es la integridad del mensaje: El cliente y el servicio web deben poder verificar que los mensajes que reciben son los que pretendía enviar la otra parte, y que el mensaje no ha sido alterado en tránsito. Esto se consigue firmando los mensajes con firmas digitales y utilizando la autenticación de certificados.

3.2 conexiones de SSL

Para establecer y mantener conexiones seguras con los clientes, los servicios web pueden utilizar Secure Sockets Layer (SSL), soportado por el Protocolo Seguro de Transferencia de Hipertexto (HTTPS). SSL garantiza la confidencialidad e integridad de los mensajes gracias al cifrado de clave pública y a los certificados de servidor. SSL ha sido sustituido por Transport Layer Security (TLS), pero a menudo se hace referencia a TLS como SSL.

Cuando un cliente solicita acceso a un recurso de un servidor, SSL inicia un proceso de negociación con el servidor. Es lo que se denomina handshake SSL. Se acuerda un nivel de cifrado, un conjunto de claves de cifrado públicas y privadas y la información de identidad de los certificados del cliente y el servidor como base de toda comunicación mientras dure la conexión SSL. El servidor también puede requerir que el cliente se autentique en este momento. Una vez establecida la conexión, todos los mensajes se cifran con la clave pública negociada hasta que se cierra la conexión.

3.2.1 Anclaje SSL

Aunque SSL puede proporcionar confidencialidad de los mensajes mediante cifrado y certificados, no hace nada para verificar que el servidor con el que se está comunicando el cliente es el correcto. El comportamiento del servidor puede ser imitado por un tercero no autorizado, interceptando los datos sensibles que el cliente transmite. Para evitar esto, se utiliza una técnica llamada SSL pinning para verificar que el certificado del servidor es el certificado que el cliente espera y en el que confía.

Hay varias formas de implementar el anclaje SSL en las aplicaciones, cada una con sus pros y sus contras. La forma más sencilla es mediante la declaración de certificados en el manifiesto del paquete de la aplicación. Esta declaración permite que el paquete de la aplicación instale certificados digitales y especifique la confianza exclusiva en ellos. El resultado es que las conexiones SSL solo se permiten entre la aplicación y los servidores que tienen los certificados correspondientes en su cadena de certificados. Este mecanismo también permite el uso seguro de certificados autofirmados, ya que no es necesario depender de terceros en cuanto a autoridades de certificación públicas de confianza.

ssl manifest

Para un mayor control sobre la lógica de validación, se dispone de API para validar los certificados devueltos por el servidor en respuesta a una solicitud HTTPS. Tenga en cuenta que este método requiere enviar una solicitud e inspeccionar la respuesta, así que asegúrese de añadir esto como una validación antes de enviar realmente información sensible en una solicitud.

El siguiente código C# ilustra este método de anclaje SSL. El método ValidateSSLRoot utiliza la clase HttpClient para ejecutar una petición HTTP. Después de que el cliente envía la respuesta, utiliza la colección RequestMessage.TransportInformation.ServerIntermediateCertificates para inspeccionar los certificados devueltos por el servidor. A continuación, el cliente puede validar toda la cadena de certificados con las miniaturas que ha incluido. Este método requiere que las huellas del certificado se actualicen en la aplicación cuando el certificado del servidor caduque y se renueve.

private async Task ValidateSSLRoot()
{
    // Send a get request to Bing
    var httpClient = new HttpClient();
    var bingUri = new Uri("https://www.bing.com");
    HttpResponseMessage response = 
        await httpClient.GetAsync(bingUri);

    // Get the list of certificates that were used to
    // validate the server's identity
    IReadOnlyList<Certificate> serverCertificates = response.RequestMessage.TransportInformation.ServerIntermediateCertificates;
  
    // Perform validation
    if (!ValidateCertificates(serverCertificates))
    {
        // Close connection as chain is not valid
        return;
    }
    // Validation passed, continue with connection to service
}

private bool ValidateCertificates(IReadOnlyList<Certificate> certs)
{
    // In this example, we iterate through the certificates
    // and check that the chain contains
    // one specific certificate we are expecting
    foreach (var cert in certs)
    {
        byte[] thumbprint = cert.GetHashValue();

        // Check if the thumbprint matches whatever you 
        // are expecting
        var expected = new byte[] { 212, 222, 32, 208, 94, 102, 
            252, 83, 254, 26, 80, 136, 44, 120, 219, 40, 82, 202, 
            228, 116 };

        // ThumbprintMatches does the byte[] comparison 
        if (ThumbprintMatches(thumbprint, expected))
        {
            return true;
        }
    }
    return false;
}

3.3 Publicar y asegurar el acceso a las API REST

Para garantizar el acceso autorizado a los servicios web, estos deben requerir autenticación cada vez que se realiza una llamada a la API. Poder controlar el rendimiento y la escala también es algo a tener en cuenta cuando los servicios web se exponen a través de la web. Azure API Management es un servicio que puede ayudar a exponer API a través de la web, al tiempo que proporciona funciones en tres niveles.

Los editores/administradores de la API pueden configurarla fácilmente a través del portal de editores de Azure API Management. Aquí se pueden crear conjuntos de API y gestionar el acceso a ellos para controlar quién tiene acceso a qué API.

Los desarrolladores que deseen acceder a estas API pueden realizar solicitudes a través del Portal para desarrolladores, que puede proporcionar acceso inmediato o requerir la aprobación del editor/administrador. Los desarrolladores también pueden consultar la documentación de la API y el código de muestra en el Portal para desarrolladores, para adoptar rápidamente las API que ofrece el servicio web.

Las aplicaciones que crean estos desarrolladores acceden entonces a la API a través del proxy que ofrece Azure API Management. El proxy proporciona una capa de oscuridad, ocultando el punto final real de la API en el servidor del editor/administrador y también puede incluir lógica adicional como la traducción de API para garantizar que la API expuesta se mantiene coherente cuando una llamada a una API se redirige a otra. También puede utilizar el filtrado de IP para bloquear las llamadas a la API que se originen en un dominio IP específico o en un conjunto de dominios. Azure API Management también mantiene la seguridad de sus servicios web mediante el uso de un conjunto de claves públicas, denominadas claves de API, para autenticar y autorizar cada llamada a la API. Cuando falla la autorización, se bloquea el acceso a la API y a la funcionalidad que soporta.

Azure API Management también puede reducir el número de llamadas API a un servicio (un procedimiento denominado estrangulamiento) para optimizar el rendimiento del servicio web. Para obtener más información, revise Azure API Management y Azure API Management en AzureCon 2015.

4 Métodos de seguridad de datos en reposo

Cuando los datos llegan a un dispositivo, nos referimos a ellos como "data-at-rest". Estos datos deben almacenarse en el dispositivo de forma segura, para que no puedan acceder a ellos usuarios o apps no autorizados. El modelo de aplicaciones de Windows 10 y Windows 11 hace mucho para garantizar que los datos almacenados por cualquier aplicación solo sean accesibles para esa aplicación, al tiempo que proporciona API para compartir los datos cuando sea necesario. También se dispone de API adicionales para garantizar que los datos se puedan cifrar y que las credenciales se puedan almacenar de forma segura.

4.1 Modelo de aplicación de Windows

Tradicionalmente, Windows nunca ha tenido una definición de aplicación. Lo más habitual era referirse a ella como un ejecutable (.exe), y esto nunca incluía la instalación, el almacenamiento del estado, la duración de la ejecución, el versionado, la integración con el sistema operativo o la comunicación entre apps. El modelo de la Plataforma Universal de Windows define un modelo de aplicación que abarca la instalación, el entorno de ejecución, la gestión de recursos, las actualizaciones, el modelo de datos y la desinstalación.

Las aplicaciones de Windows 10 se ejecutan en un contenedor, lo que significa que tienen privilegios limitados por defecto (el usuario puede solicitar y conceder privilegios adicionales). Por ejemplo, si una aplicación desea acceder a los archivos del sistema, debe utilizar un selector de archivos del espacio de nombres Windows.Storage.Pickers para que el usuario pueda seleccionar un archivo (no se permite el acceso directo a los archivos). Otro ejemplo es si una aplicación quiere acceder a los datos de localización del usuario, necesita habilitar la capacidad del dispositivo de localización que debe ser declarada, preguntando al usuario en el momento de la descarga que esta aplicación solicitará acceso a la localización del usuario. Además, la primera vez que la aplicación quiera acceder a la ubicación del usuario, se le mostrará una solicitud de consentimiento adicional para acceder a los datos.

Tenga en cuenta que este modelo de aplicación actúa como una "cárcel" para las aplicaciones, lo que significa que no pueden salir, pero no es un "castillo" al que no se pueda acceder desde el exterior (por supuesto, las aplicaciones con privilegios de administrador pueden entrar). Device Guard en Windows 10 y Windows 11, que permite a las organizaciones/TI especificar qué aplicaciones (Win32) pueden ejecutarse, puede ayudar a limitar aún más este acceso.

El modelo de aplicación también gestiona el ciclo de vida de las aplicaciones. Por ejemplo, limita la ejecución en segundo plano de las aplicaciones de forma predeterminada; en cuanto una aplicación pasa a segundo plano, el proceso se suspende, después de dar a la aplicación un breve período para abordar la suspensión de la aplicación en el código, y su memoria se congela. El sistema operativo proporciona mecanismos para que las aplicaciones soliciten la ejecución de tareas específicas en segundo plano (de forma programada, activadas por diversos eventos como la conectividad a Internet/Bluetooth, cambios de alimentación, etc., y en escenarios específicos como la reproducción de música o el seguimiento GPS).

Cuando los recursos de memoria del dispositivo se agotan, Windows libera espacio de memoria cerrando las aplicaciones. Este modelo de ciclo de vida obliga a las aplicaciones a persistir en los datos cada vez que se suspenden, ya que no hay tiempo adicional disponible entre la suspensión y la terminación.

Para obtener más información, consulta Es universal: Comprender el ciclo de vida de una aplicación Windows 10/11.

4.2 Protección de credenciales almacenadas

Las aplicaciones de Windows que acceden a servicios autenticados a menudo ofrecen a los usuarios la opción de almacenar sus credenciales en el dispositivo local. Esto es una comodidad para los usuarios; cuando proporcionan su nombre de usuario y contraseña, la aplicación los utiliza automáticamente en posteriores lanzamientos de la aplicación. Dado que esto puede suponer un problema de seguridad si un atacante consigue acceder a estos datos almacenados, Windows 10 y Windows 11 ofrecen la posibilidad de que las aplicaciones de Windows almacenen las credenciales de los usuarios en una caja de seguridad de credenciales seguro. La aplicación llama a la API de la Caja de seguridad de credenciales para almacenar y recuperar las credenciales de la caja de seguridad en lugar de almacenarlas en el contenedor de almacenamiento de la aplicación. El sistema operativo gestiona la caja de seguridad de credenciales, pero el acceso está limitado a la aplicación que las almacena, lo que proporciona una solución gestionada de forma segura para el almacenamiento de credenciales.

Cuando un usuario proporciona las credenciales que desea almacenar, la aplicación obtiene una referencia al almacén de credenciales mediante el objeto PasswordVault del espacio de nombres Windows.Security.Credentials. A continuación, crea un objeto PasswordCredential que contiene un identificador para la aplicación de Windows y el nombre de usuario y la contraseña. Esto se pasa al método PasswordVault.Add para almacenar las credenciales en la caja de seguridad. El siguiente ejemplo de código C# muestra cómo se hace esto.

var vault = new PasswordVault();
vault.Add(new PasswordCredential("My App", username, password));

En el siguiente ejemplo de código C#, la aplicación solicita todas las credenciales correspondientes a la aplicación llamando al método FindAllByResource del objeto PasswordVault. Si se devuelve más de una, pide al usuario que introduzca su nombre de usuario. Si las credenciales no están en el casillero, la aplicación se las pide al usuario. A continuación, el usuario inicia sesión en el servidor utilizando las credenciales.

private string resourceName = "My App";
private string defaultUserName;

private void Login()
{
    PasswordCredential loginCredential = GetCredentialFromLocker();

    if (loginCredential != null)
    {
        // There is a credential stored in the locker.
        // Populate the Password property of the credential
        // for automatic login.
        loginCredential.RetrievePassword();
    }
    else
    {
        // There is no credential stored in the locker.
        // Display UI to get user credentials.
        loginCredential = GetLoginCredentialUI();
    }
    // Log the user in.
    ServerLogin(loginCredential.UserName, loginCredential.Password);
}

private PasswordCredential GetCredentialFromLocker()
{
    PasswordCredential credential = null;

    var vault = new PasswordVault();

    IReadOnlyList<PasswordCredential> credentialList = null;

    try
    {
        credentialList = vault.FindAllByResource(resourceName);
    }
    catch(Exception)
    {
        return null;
    }

    if (credentialList.Count == 1)
    {
        credential = credentialList[0];
    }
    else if (credentialList.Count > 0)
    {
        // When there are multiple usernames,
        // retrieve the default username. If one doesn't
        // exist, then display UI to have the user select
        // a default username.
        defaultUserName = GetDefaultUserNameUI();

        credential = vault.Retrieve(resourceName, defaultUserName);
    }
    return credential;
}

Para más información, consulte el apartado Caja de seguridad de credenciales.

4.3 Protección de datos almacenados

Cuando se trata de datos almacenados, comúnmente conocidos como datos en reposo, cifrarlos puede evitar que usuarios no autorizados accedan a los datos almacenados. Los dos mecanismos habituales para cifrar datos son el uso de claves simétricas o el uso de claves asimétricas. Sin embargo, el cifrado de datos no puede garantizar que los datos permanezcan inalterados entre el momento en que se enviaron y el momento en que se almacenaron. En otras palabras, no se puede garantizar la integridad de los datos. El uso de códigos de autenticación de mensajes, hashes y firmas digitales son técnicas habituales para resolver este problema.

4.3.1 Cifrado de datos

Con el cifrado simétrico, tanto el remitente como el destinatario tienen la misma clave y la utilizan tanto para cifrar como para descifrar los datos. El problema es compartir la clave de forma segura para que ambas partes la conozcan.

Una solución es el cifrado asimétrico, en el que se utiliza un par de claves pública/privada. La clave pública se comparte libremente con cualquiera que quiera cifrar un mensaje. La clave privada se mantiene siempre en secreto, de modo que solo uno puede utilizarla para descifrar los datos. Una técnica habitual para permitir el descubrimiento de la clave pública es el uso de certificados digitales, también denominados simplemente certificados. El certificado contiene información sobre la clave pública, además de información sobre el usuario o el servidor, como el nombre, el emisor, la dirección de correo electrónico y el país.

Los desarrolladores de aplicaciones Windows pueden utilizar las clases SymmetricKeyAlgorithmProvider y AsymmetricKeyAlgorithmProvider para implementar el cifrado simétrico y asimétrico en sus aplicaciones UWP. Además, la clase CryptographicEngine puede utilizarse para cifrar y descifrar datos, firmar contenidos y verificar firmas digitales. Las aplicaciones también pueden utilizar la clase DataProtectionProvider del espacio de nombres Windows.Security.Cryptography.DataProtection para cifrar y descifrar datos locales almacenados.

4.3.2 Detección de manipulación de mensajes (MAC, hashes y firmas)

Un MAC es un código (o etiqueta) que resulta de usar una clave simétrica (llamada clave secreta) o un mensaje como entrada a un algoritmo de encriptación MAC. La clave secreta y el algoritmo son acordados por el emisor y el receptor antes de la transferencia del mensaje.

Los MAC verifican así los mensajes.

  • El emisor obtiene la etiqueta MAC utilizando la clave secreta como entrada para el algoritmo MAC.
  • El emisor envía la etiqueta MAC y el mensaje al receptor.
  • El receptor obtiene la etiqueta MAC utilizando la clave secreta y el mensaje como entradas para el algoritmo MAC.
  • El receptor compara su etiqueta MAC con la etiqueta MAC del emisor. Si coinciden, sabemos que el mensaje no ha sido manipulado.

mac verification

Las aplicaciones Windows pueden implementar la verificación de mensajes MAC llamando a la clase MacAlgorithmProvider para generar la clave y a la clase CryptographicEngine para realizar el algoritmo de cifrado MAC.

4.3.3 Uso de hashes

Una función hash es un algoritmo criptográfico que toma un bloque de datos arbitrariamente largo y devuelve una cadena de bits de tamaño fijo llamada valor hash. Hay toda una familia de funciones hash que pueden hacer esto.

Un valor hash puede utilizarse en lugar de una MAC en el escenario de transferencia de mensajes anterior. El remitente envía un valor hash y un mensaje, y el receptor obtiene su propio valor hash a partir del valor hash y el mensaje del remitente y compara los dos valores hash. Las aplicaciones que se ejecutan en Windows 10 y Windows 11 pueden llamar a la clase HashAlgorithmProvider para enumerar los algoritmos hash disponibles y ejecutar uno de ellos. La clase CryptographicHash representa el valor hash. El método CryptographicHash.GetValueAndReset se puede utilizar para hacer hash de diferentes datos repetidamente sin tener que volver a crear el objeto para cada uso. El método Append de la clase CryptographicHash añade nuevos datos a un buffer para ser sometidos a hash. Todo este proceso se muestra en el siguiente ejemplo de código C#.

public void SampleReusableHash()
{
    // Create a string that contains the name of the
    // hashing algorithm to use.
    string strAlgName = HashAlgorithmNames.Sha512;

    // Create a HashAlgorithmProvider object.
    HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(strAlgName);

    // Create a CryptographicHash object. This object can be reused to continually
    // hash new messages.
    CryptographicHash objHash = objAlgProv.CreateHash();

    // Hash message 1.
    string strMsg1 = "This is message 1";
    IBuffer buffMsg1 = CryptographicBuffer.ConvertStringToBinary(strMsg1, BinaryStringEncoding.Utf16BE);
    objHash.Append(buffMsg1);
    IBuffer buffHash1 = objHash.GetValueAndReset();

    // Hash message 2.
    string strMsg2 = "This is message 2";
    IBuffer buffMsg2 = CryptographicBuffer.ConvertStringToBinary(strMsg2, BinaryStringEncoding.Utf16BE);
    objHash.Append(buffMsg2);
    IBuffer buffHash2 = objHash.GetValueAndReset();

    // Convert the hashes to string values (for display);
    string strHash1 = CryptographicBuffer.EncodeToBase64String(buffHash1);
    string strHash2 = CryptographicBuffer.EncodeToBase64String(buffHash2);
}

4.3.4 Firmas digitales

La integridad de los datos de un mensaje almacenado firmado digitalmente se verifica de forma similar a la autenticación MAC. Así es como funciona el flujo de trabajo de la firma digital.

  • El remitente obtiene un valor hash (también conocido como compendio) utilizando el mensaje como entrada de un algoritmo hash.
  • El remitente cifra el resumen utilizando su clave privada.
  • El emisor envía el mensaje, el resumen cifrado y el nombre del algoritmo hash utilizado.
  • El receptor utiliza la clave pública para descifrar el resumen cifrado que ha recibido. A continuación, utiliza el algoritmo hash para descomponer el mensaje y crear su propio resumen. Por último, el receptor compara los dos compendios (el que ha recibido y descifrado y el que ha creado). Solo si los dos coinciden, el receptor puede estar seguro de que el mensaje fue enviado por el poseedor de la clave privada y, por tanto, es quien dice ser, y de que el mensaje no fue alterado en tránsito.

digital signatures

Los algoritmos hash son muy rápidos, por lo que los valores hash pueden obtenerse rápidamente incluso de mensajes de gran tamaño. El valor hash resultante tiene una longitud arbitraria y puede ser más corto que el mensaje completo, por lo que utilizar claves públicas y privadas para cifrar y descifrar solo el resumen en lugar del mensaje completo es una optimización.

Para obtener más información, echa un vistazo a los artículos sobre Firmas digitales, MAC, hashes y firmas y Criptografía.

5 Resumen

La Plataforma Universal de Windows en Windows 10 y Windows 11 ofrece varias formas de aprovechar las capacidades del sistema operativo para crear aplicaciones más seguras. En diferentes escenarios de autenticación, como la autenticación de factor único, multifactor o la autenticación intermediada con un proveedor de identidad OAuth, existen API para mitigar los desafíos más comunes de la autenticación. Windows Hello proporciona un nuevo sistema de inicio de sesión biométrico que reconoce al usuario y derrota activamente los esfuerzos por eludir la identificación adecuada. También ofrece múltiples capas de claves y certificados que nunca pueden ser revelados o utilizados fuera del módulo de la plataforma de confianza. Además, se dispone de una capa adicional de seguridad mediante el uso opcional de claves y certificados de identidad de atestación.

Para proteger los datos en tránsito, existen API que se comunican con sistemas remotos de forma segura a través de SSL, al tiempo que ofrecen la posibilidad de validar la autenticidad del servidor con anclaje SSL. La publicación de APIs de forma segura y controlada es algo en lo que Azure API Management ayuda proporcionando potentes opciones de configuración para exponer APIs a través de la web utilizando un proxy que proporciona ofuscación adicional del punto final de la API. El acceso a estas API está protegido mediante el uso de claves de API y las llamadas a la API se pueden limitar para controlar el rendimiento.

Cuando los datos llegan al dispositivo, el modelo de aplicación de Windows proporciona más control sobre cómo se instala la aplicación, cómo se actualiza y cómo accede a sus datos, al tiempo que evita que acceda a los datos de otras aplicaciones de forma no autorizada. Caja de seguridad de credenciales puede proporcionar un almacenamiento seguro de las credenciales de usuario gestionado por el sistema operativo, y otros datos pueden protegerse en el dispositivo utilizando las API de cifrado y hashing que ofrece la Plataforma Universal de Windows.

6. Recursos

6.1 Artículos prácticos

6.2 Ejemplos de código

6.3 Referencia API