2012-06-28 14 views
8

Estoy desarrollando una aplicación para Android, y necesito usar java Signature class para la autenticación de datos.SHA256 con firma RSA devuelve diferentes salidas en varios dispositivos Android

En cada dispositivo Android, puedo firmar los datos y verificar su firma. Sin embargo, dado un trozo definido de datos para firmar, un módulo definido, un exponente privado definido y un exponente público definido, los resultados de mis firmas son diferentes, dependiendo de los dispositivos. Lo intenté con muchos dispositivos, y obtuve las mismas firmas para Android 3.2 y 3.2.1, pero diferentes para un dispositivo con Android 2.2.x.

Calculo estas firmas a partir de campos constantes que he generado previamente usando KeyFactory con RSA en un proyecto Java. El tamaño de la clave es 2048bit.

Aquí hay una cita del código que utilizo para invocar Firma y verificación.

public byte[] signData(byte[] data, PrivateKey privateKey) throws ... { 
     Signature signature = Signature.getInstance("SHA256withRSA"); 
     signature.initSign(privateKey); 
     signature.update(data); 
     return signature.sign(); 
} 

public boolean verifyData(byte[] data, byte[] sigBytes, PublicKey publicKey) throws ... { 
     Signature signature = Signature.getInstance("SHA256withRSA"); 
     signature.initVerify(publicKey); 
     signature.update(data); 
     return signature.verify(sigBytes); 
} 

Si no me equivoco, la firma con SHA256 con RSA es determinista. Entonces, ¿cómo puedo explicar tal comportamiento? Otra pregunta interesante, ¿cómo podría hacer que funcione en dispositivos cruzados, es decir, las firmas serían las mismas, no importa qué dispositivo utilizo?

Gracias de antemano, Franck!

+0

El código se ve bien, aunque pegar los controladores de error apenas era necesario. Asegúrese de que la clave y la información que se va a firmar sean las mismas. –

+0

@SevaAlekseyev Sí, estoy seguro de que todas las entradas de mi sistema son las mismas. Los codifiqué como finales estáticos, en una clase, que contienen estas constantes. No vinculé los valores constantes por conveniencia. – franckysnow

+0

Depurar paso a paso. Primero, calcule los hash SHA256 en todas esas plataformas y compárelos. –

Respuesta

11

Sí, SHA256withRSA es completamente determinista.

En teoría, podría verse afectado por un error (see an example) en una versión de la biblioteca BouncyCastle modificada antigua que se encuentra en una de las versiones de Android. Tal error podría ser eliminado si usó SHA512withRSA en su lugar, bueno, al menos el que se hace referencia sería.

Sin embargo, antes de comenzar a profundizar en el algoritmo hash, verifique cerca de casa.

Quizás haya obtenido su conjunto de bytes mediante una llamada al String.getBytes. Esta llamada depende de la codificación de plataforma predeterminada que es different entre Android 2.2 y Android 2.3. Esto implica que, si bien sus cadenas son las mismas en ambos casos, las matrices de bytes podrían no serlo.

Para obtener la codificación bajo control, y crea su plataforma de código independiente, especifique la codificación como un parámetro:

plainText.getBytes("UTF-8") 

En caso contrario, hay un poco más de tácticas para conseguir una aplicación independiente de la plataforma.

  • espera hasta 2.2 con la biblioteca, presumiblemente, con errores se extingue
  • distribuir una buena biblioteca conocido (frasco) con su software. Si eso fuera BouncyCastle, tendrás problemas para asegurarte de que tus clases y las de Android no estén cargadas. La solución se llama SpongyCastle.
  • juego con alineación/relleno. Intente hacer que la longitud del mensaje en bytes sea congruente con 0,55, 56 o 63 módulo 64 agregando su propio relleno fijo y espero que una de estas opciones comience a dar firmas portátiles. Estos valores se eligen para interactuar con la parte más externa del algoritmo sospechoso que está rellenando bloques de 512 bits.
+0

Gracias por su respuesta Jirka. Cambié 'SHA256withRSA' a' SHA512withRSA', pero no se ha solucionado el problema. Todavía tengo la misma firma para un dispositivo Android 3.2.1 y 3.2, y el emulador (2.1) aún obtiene una firma diferente. La entrada no es una 'Cadena' sino un' byte '[] 'codificado. ¿Alguna otra idea por casualidad? – franckysnow

+0

También obtengo el mismo resultado que para 3.2.1 y 3.2 con un dispositivo emulado 4.0.3. – franckysnow

+1

@FranckStudiesCommEng - respuesta expandida por tres rutas que consideraría a continuación. –

Cuestiones relacionadas