¿Los datos de firma son mayores que el tamaño de bloque RSA permitido?

3

He encontrado un pequeño problema al implementar una versión modificada del Protocolo estación a estación (STS). Digamos que tenemos dos directores A y B, donde ambos conocen la clave pública del otro:

  1. A- > B: Ta (valor público de DH)
  2. B- > A: Tb, SigB (Tb, Ta, A)
  3. A- > B: SigA (Ta, Tb, B)

Para el segundo mensaje de protocolo, quiero encriptar (usando mi clave privada) algunos datos usando encriptación de clave pública (por ejemplo, RSA); y como STS es un protocolo de acuerdo de clave utilizado para establecer una clave secreta, no se puede usar el cifrado simétrico como AES o 3DES.

Por otra parte, pensé en simplemente aplicar hash a los datos a un tamaño fijo (utilizando, por ejemplo, SHA-1) y luego firmarlos; sin embargo, eso tampoco funcionará, ya que la otra parte debe poder extraer las diferentes partes del mensaje firmado para una verificación de verificación posterior.

En caso de que no estuviera claro: SigB(Tb,Ta,A) donde SigB significa firmar usando la clave privada B, y debo poder recuperar Ta, Tb y A.

¿Hay alguna otra forma además de dividir los datos en bloques y luego firmar cada uno de esos bloques (BCE, que es vulnerable al análisis criptográfico)?

Aquí está el código que genera el DHparamspec .

protected AlgorithmParameterSpec generateParameters() {
    DHParameterSpec spec = null;
    try {
        AlgorithmParameterGenerator apg = AlgorithmParameterGenerator
                .getInstance("DH");
        apg.init(1024);
        AlgorithmParameters algParam = apg.generateParameters();
        spec = (DHParameterSpec)algParam
                .getParameterSpec(DHParameterSpec.class);


    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (InvalidParameterSpecException e) {
        e.printStackTrace();
    }
    return spec; // something went wrong
}

Y el código que genera el par DH.

kf = KeyFactory.getInstance("DH");
            keyGen = KeyPairGenerator.getInstance("DH", "BC");
            keyGen.initialize(paramSpec);

            keyPair = keyGen.generateKeyPair();

            kAgreement = KeyAgreement.getInstance("DH");
            kAgreement.init(keyPair.getPrivate());
    
pregunta me_L_coding 30.07.2012 - 21:02
fuente

2 respuestas

4

Woah. Esto es un poco desordenado. Revisemos esto paso a paso.

Primero que nada: no debes diseñar o implementar tu propio protocolo criptográfico. Por favor, no tome esto personalmente, pero: usted no está calificado. E incluso aquellos que están calificados se esfuerzan por evitar hacer esto, porque es muy fácil cometer errores sutiles. No enrolle su propio criptográfico .

En su lugar, debería estar utilizando TLS. Sólo úsalo; está bien revisado, hay muchas implementaciones ampliamente disponibles y resuelve su problema. No hay una buena razón para implementar otra cosa, y todas las razones para evitar hacerlo. Han sido necesarios muchos años, e innumerables décadas de experiencia profesional, para resolver las arrugas y los problemas de seguridad en el TLS. Simplemente no puede permitirse hacer eso por su propio protocolo y su propio código. Ni siquiera deberías intentarlo: deberías reutilizar el esfuerzo que ya se ha puesto en TLS.

Usa TLS. Problema resuelto. ¡Ahora puedes dedicar tu tiempo a algo más útil!

(Para responder a la pregunta que realmente hizo, si desea firmar un mensaje largo, el método estándar es hacer un hash primero con un hash resistente a la colisión y firmar el hash. De hecho, esta técnica ya está incorporada a todos los públicos El esquema de firma de teclas que he visto, por lo que realmente no necesita hacer nada especial: ya hacen el hashing. [Ciertamente espero que no esté tratando de hacer una firma RSA sin ningún tipo de relleno; eso es terriblemente inseguro. ] No pude entender su explicación, no puede simplemente usar los algoritmos de firma digital estándar; sospecho que puede haberse confundido o haberse torcido en nudos o algo así. Pero en cualquier caso, todo esto es irrelevante: usted No debe diseñar o implementar criptografía en este nivel de abstracción. La mejor manera de responder su pregunta es anular la pregunta y señalarle en una dirección diferente.)

    
respondido por el D.W. 31.07.2012 - 08:51
fuente
2

El RSA sin formato no es un esquema de firma . Es sólo un componente de un esquema de firma. Los esquemas reales de firma o cifrado basados en RSA también incluyen relleno : en su lugar de aplicar la operación RSA sin procesar ( m md mod n o < em> m ↦ me mod n ) al mensaje, se aplica al mensaje concatenación de algún texto de relleno y el mensaje. Este relleno tiene dos funciones principales:

  • Asegura que la operación RSA no se aplique a un número que sea demasiado pequeño. Esto evita que una serie de relaciones matemáticas rompan la seguridad del uso de RSA, la más simple es que si calcula me mod n con m y e pequeños, en realidad no se produce ninguna reducción de módulo.
  • Asegura que la operación RSA nunca se aplique dos veces al mismo mensaje. Para el cifrado, esto evita que un atacante rompa el mensaje por fuerza bruta (probando cada posible texto sin formato). Para las firmas, esto evita que surjan varias relaciones matemáticas cuando se firman los mensajes relacionados.

Para obtener información más detallada sobre la función del relleno, consulte ¿Es RSA una fuente aleatoria sin relleno? ¿El relleno RSA tiene que ser impredecible si la carga útil es? ¿Se necesita el relleno RSA para un solo destinatario, un solo mensaje aleatorio único?

Hay dos esquemas de relleno comunes para las firmas RSA: RSA-PSS y RSA-PKCS1.5. Ambos están definidos por el documento PKCS # 1 que define RSA. No los explicaré aquí, lea el PKCS # 1 document para su definicion Ambos métodos requieren que el mensaje esté primero hash con una función de resumen criptográfico como SHA-256 o SHA-512 (o su predecesor SHA -1 ). Por lo tanto, una firma RSA real de un mensaje arbitrario¹ se ve así:

RSA(key, message) = RSA_operation(key, padding ++ hash(message))

El hash comprime la información relevante sobre el mensaje (a saber, si un mensaje supuesto es igual al mensaje genuino) en un tamaño acotado. Al hacer el cifrado, tal compresión no es posible. Para cifrar datos de tamaño arbitrario con RSA, el método habitual es generar una clave secreta aleatoria (a menudo llamada clave de sesión), cifrar el mensaje real con esa clave y enviar la clave secreta cifrada con RSA. Consulte Cómo ¿Puedo usar cifrado asimétrico, como RSA, para cifrar una longitud arbitraria de texto plano?

¹ Técnicamente, hay límites, pero no los encontrará en la práctica: SHA-1 y SHA-256 pueden ejecutar hasta 2 61 -1 bytes, SHA-512 hasta 2 125 -1 bytes.

    
respondido por el Gilles 31.07.2012 - 20:59
fuente

Lea otras preguntas en las etiquetas