¿Se debe firmar y cifrar con la misma clave? Los laboratorios de entrenamiento de Azure están adoptando este enfoque.

8

Estoy tomando el laboratorio de Azure LoadBalancing con WCF y reconozco que lo que me han dicho es malo de una perspectiva de seguridad, pero no estoy seguro de si se aplica aquí.

¿Alguien puede mirar este código y decirme si se deben usar certificados diferentes en el código de producción?

public class RsaSessionSecurityTokenHandler : SessionSecurityTokenHandler
    {
        public RsaSessionSecurityTokenHandler(X509Certificate2 certificate)
        {
            List<CookieTransform> transforms = new List<CookieTransform>();
            transforms.Add(new DeflateCookieTransform());
            transforms.Add(new RsaEncryptionCookieTransform(certificate));
            transforms.Add(new RsaSignatureCookieTransform(certificate));
            this.SetTransforms(transforms);
        }

        public override ClaimsIdentityCollection ValidateToken(SessionSecurityToken token, string endpointId)
        {
            if (token == null)
            {
                throw new ArgumentNullException("token");
            }
            if (String.IsNullOrEmpty(endpointId))
            {
                throw new ArgumentException("endpointId");
            }

            // in active cases where absolute uris are used check the all parts of the token's 
            // endpoint id and this endpoint's id for equality except the port number
            Uri listenerEndpointId;
            bool listenerHasUri = Uri.TryCreate(endpointId, UriKind.Absolute, out listenerEndpointId);
            Uri tokenEndpointId;
            bool tokenHasUri = Uri.TryCreate(token.EndpointId, UriKind.Absolute, out tokenEndpointId);
            if (listenerHasUri && tokenHasUri)
            {
                if (listenerEndpointId.Scheme != tokenEndpointId.Scheme ||
                    listenerEndpointId.DnsSafeHost != tokenEndpointId.DnsSafeHost ||
                    listenerEndpointId.AbsolutePath != tokenEndpointId.AbsolutePath)
                {
                    throw new SecurityTokenValidationException(String.Format("The incoming token for '{0}' is not scoped to the endpoint '{1}'.", tokenEndpointId, listenerEndpointId));
                }
            }
            // in all other cases, fall back to string comparison
            else if (String.Equals(endpointId, token.EndpointId, StringComparison.Ordinal) == false)
            {
                throw new SecurityTokenValidationException(String.Format("The incoming token for '{0}' is not scoped to the endpoint '{1}'.", token.EndpointId, endpointId));
            }

            return this.ValidateToken(token);
        }
    }
    
pregunta random65537 15.04.2011 - 05:07
fuente

5 respuestas

5

Muchos han señalado el depósito de claves como una razón para separar las claves de cifrado y firma. Muchos también han mencionado que este uso compartido de claves está bien en este caso particular. Pero nadie ha mencionado los problemas criptográficos al compartir claves para la firma y el cifrado

Si observas los estándares oficiales para la criptografía, la mayoría de ellos especifican que se usan claves diferentes para algoritmos diferentes. Para los certificados X509, la parte de uso de la clave tiene controles muy específicos para el uso de la clave. Y, por ejemplo, NIST tiene esto que decir acerca de las teclas de curva elíptica:

  

Las claves ECDSA solo se utilizarán para la generación y verificación de firmas digitales ECDSA.

El motivo de esto es que si se utilizan varios algoritmos diferentes con la misma clave, entonces se debe probar la seguridad para la combinación de todos los algoritmos juntos, en lugar de solo para un algoritmo. De lo contrario, un atacante podría usar un algoritmo para producir un valor que él mismo no pudo calcular para atacar la seguridad de otro algoritmo.

Por ejemplo, hipotéticamente, un protocolo de acuerdo clave que firma valores remotos arbitrarios podría usarse para falsificar firmas válidas. O tal vez el envío de una clave pública para su firma podría revelar un valor útil para atacar un acuerdo clave. O concretamente en el caso de RSA, si no se usó el relleno seguro, el envío de un valor para ser firmado puede dar un descifrado de un texto cifrado si se usa la misma clave.

Entonces, a menos que esté muy seguro de que tanto los algoritmos de firma como los de encriptación se pueden usar junto con la misma clave, de manera segura, no debería hacer eso. Incluso si estás muy seguro, es una mala práctica criptográfica. Y si necesitas seguir estándares, no te lo permitirán, de todos modos.

    
respondido por el Nakedible 16.08.2011 - 22:21
fuente
6

Es una práctica recomendada general usar dos pares de claves separados (y, por lo tanto, certificados) para la firma frente al cifrado. Acabo de refrescarme en las razones por las que:

  • Cuando se usa una clave para el cifrado, A menudo es prudente depositarlo para que Si se pierde, el contenido encriptado. tampoco se pierde. Sin embargo, no repudio asociado a una certificado de firma no es viable Con varias copias del par de claves. alrededor. Así que no quieres depositar El certificado de firma. Desde Wikipedia

Es el mejor que he escuchado. La mayoría de las veces lo que me dicen es "simplemente hazlo", y dado que a menudo uno tiene que trabajar dentro de las limitaciones de la PKI que uno está obligado a usar, esa es una declaración bastante justa.

Personalmente, creo que para una PKI simple, agrupar los dos juntos, especialmente si está utilizando las capacidades de "cifrado" de la clave para algo como SSL, un tipo de cifrado transitorio para la comunicación punto a punto, entonces la seguridad el riesgo no es tan alto.

Sin embargo, a veces debe estar listo para trabajar con cualquier PKI que se presente. Por lo tanto, si el código tenía una codificación rígida, se supone que el certificado de cifrado y el certificado de firma siempre serán lo mismo, entonces creo que tiene un problema de interoperabilidad.

Como una última cosa, estoy un poco confundido con el código, asumo que "ValidateToken" hace la validación de la firma en el token, ¿verdad? No se puede descifrar y validar la firma utilizando el mismo par de claves ... el cifrado es para enviarlo al titular del par de claves, la firma es para verificar la información del titular del par de claves. ¿Está haciendo una validación de firma aquí?

    
respondido por el bethlakshmi 18.04.2011 - 17:37
fuente
4

En este escenario particular , esta técnica está bien.

Utiliza la misma clave criptográfica (en este caso, un certificado X.509) para cifrar a sí mismo. La muestra que menciona implementa un token de sesión (simplemente hablando una cookie protegida), que se comparte entre múltiples servicios web similares que se encuentran detrás de un equilibrador de carga. Por lo tanto, la "firma" (en este escenario particular) no tiene el objetivo de seguridad de proporcionar no repudio, sino de autenticación de origen de datos, es decir, básicamente, averiguar si el token de sesión fue creado por uno de los servicios pares.

NB: en otros escenarios, donde la firma cumple un objetivo de no repudio, debe utilizar material clave por separado (como se indica correctamente en las otras respuestas aquí).

    
respondido por el chgeuer 16.08.2011 - 11:54
fuente
3
  

¿Alguien puede mirar este código y decirme si se deben usar certificados diferentes en el código de producción?

Primero, cualquier código que se use para una función de seguridad debe diseñarse, revisarse su diseño, implementarse, revisarse y probarse antes de instalarse en un entorno de producción. El hecho de que el código provenga de MSDN no significa que sea seguro. Incluso si decide utilizar el código como está escrito, no omita el diseño. El diseño puede ayudarlo a notar grandes problemas en todo el sistema.

Como han señalado Bethlakshmi y Rook, el certificado se está utilizando para el cifrado (confidencialidad) y la firma digital (identificación y autenticación). En general, debe usar diferentes certificados (o teclas) para diferentes funciones. O más simplemente, un certificado debe usarse para una sola función.

En este caso, parece correcto utilizar el mismo certificado para ambas funciones. Incluso si una de las operaciones falla y el mensaje aún se envía, no parece que se exponga ninguna parte del certificado a menos que RsaEncryptionCookieTransform o RsaEncryptionCookieTransform falle. Y enviar un mensaje con un cifrado exitoso pero sin firma o firma pero sin cifrado se ve bien.

Si decide utilizar un certificado para ambas funciones, asegúrese de resaltarlo en su plan de administración de claves y en su modelo de amenaza.

    
respondido por el this.josh 16.07.2011 - 01:53
fuente
1

No hay nada de malo en este enfoque. Es importante tener en cuenta que encryption!=authentication . El uso del cifrado no garantiza que el mensaje no haya sido manipulado, sin embargo, al firmarlo, puede garantizarlo.

    
respondido por el rook 16.04.2011 - 19:20
fuente

Lea otras preguntas en las etiquetas