2011-05-20 38 views
26

estoy usando RSA para cifrar usuario y contraseña en Android y descifrarlos en el servidor (Tomcat 6, Java 1.6). cifrado Android:cifrado RSA: Diferencia entre Java y Android

PublicKey pubKey = readPublicKeyFromFile(mod, ex); 
    Cipher cipher = Cipher.getInstance("RSA"); 
    cipher.init(Cipher.ENCRYPT_MODE, pubKey); 
    byte[] cipherData = cipher.doFinal(data); 
    return cipherData; 

Java Tomcat Descifrado:

PrivateKey pubKey = readPrivateKeyFromFile(mod, ex); 
    Cipher cipher = Cipher.getInstance("RSA"); 
    cipher.init(Cipher.DECRYPT_MODE, pubKey); 
    byte[] cipherData = cipher.doFinal(data); 
    return cipherData; 

Si utilizo el androide androide FUERA parte (Sólo en un método principal) que trabaja muy bien. Pero no dentro de mi Android (Emulador). Por el lado de servidor me sale el siguiente error:

javax.crypto.BadPaddingException: Blocktype mismatch: 0 
    at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:311) 
    at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:255) 
    at com.sun.crypto.provider.RSACipher.a(DashoA13*..) 
    at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..) 
    at javax.crypto.Cipher.doFinal(DashoA13*..) 

guardo el Ministerio de Defensa y ex como constantes BigIntegers así que no escribo en un archivo. Sé que hay diferencia entre el cifrado java1.6 y java 1.5, por lo que ambos se compilan con java 1.6.

alguna información de depuración:

Durante depuración en Android que se puede ver que contiene pubkey módulo y exponente en hexadecimal. Y si depuro en un método principal (de nuevo el mismo código) puedo ver que pubKey contiene módulo y exponente en decimal.

¿Qué estoy haciendo mal?

Gracias

+1

duplicado posible: http: // stackoverflow.com/questions/4926126/rsa-encryption-in-java-cross-platform-issues –

+0

¿Realmente le llama la clave privada 'pubKey'? ¿Es esto realmente el código o simplemente tecleaste la pregunta desde la memoria? –

+0

** Advertencia ** para nuevos protocolos, pruebe y use relleno OAEP en su lugar. PKCS # 1 es vulnerable a los ataques de oráculo de relleno. –

Respuesta

1

En primer lugar, parece que estás inicializar ambos sistemas de cifrado con la clave pública. El cifrado utiliza clave pública, descifrado utilizado clave privada. Espero que sea solo un error tipográfico.

tuve un montón de problemas con el cifrado RSA, así, gran parte fue prueba y error. Te sugiero que pruebes con otro proveedor. Logré implementar RSA usando BouncyCastle.

Cipher wrapper = Cipher.getInstance("RSA", "BC"); 
wrapper.init(Cipher.ENCRYPT_MODE, publicKey); 
encryptedData= wrapper.doFinal(unencryptedData); 

Aunque, generé mi propio par de llaves ya que era una encriptación de sesión.

kpg = KeyPairGenerator.getInstance("RSA"); 
     kpg.initialize(1024); 
     KeyPair kp = kpg.genKeyPair(); 
     publicKey = kp.getPublic(); 
     privateKey = kp.getPrivate(); 
+0

+1 porque después de horas de prueba y error encontré esta publicación y resolvió mi problema. Me salvaste el culo hoy, gracias: D –

+0

La creación de un par de claves propias no es segura ya que se necesita establecer la confianza para la clave pública. Además, especificar un proveedor no es una forma portátil de codificar, y el algoritmo de la clave predeterminada puede cambiar. Solo se debe preferir especificar el algoritmo completo, incluido el modo de relleno (como en las otras respuestas), a esta solución. –

10

le sugiero que utilice la inicialización del sistema de cifrado específica: como ejemplo,

Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding"); 

funcionará en ambos. La excepción de que está recibiendo (BadPaddingException) está ocurriendo porque el relleno cifrado inicialización por defecto parece ser diferente entre la máquina virtual Java de escritorio y la JVM Android.

41

estoy haciendo RSA Cifrar en Android 2.2 + y descifrar en un Tomcat 6 java 1.6 servidor.

que estaba recibiendo este problema exacto, la lectura de todo el lugar y en parte gracias a la respuesta @Femi 's me encontré con lo que necesitaba.

La solución fue utilizar la especificación del algoritmo de cifrado para el folowing:

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 

Esto funciona haciendo cifrado tanto de los teléfonos inteligentes BlackBerry y Android. Sé que han pasado cuatro meses desde que se hizo la pregunta, pero solo en caso de que alguien más tenga este problema.

+4

Para confirmar, esta solución aún funciona en Android 4.xy Java 8. Básicamente, si usted hace Cipher.getInstance ("RSA") no funcionará, necesita especificar la más específica. – sam

+0

Esto también funciona al descifrar datos cifrados en JS. En mi caso, al usar Cipher.getInstance ("RSA") sin "/ ECB/PKCS1Padding" estaba agregando algunos caracteres adicionales antes de los datos necesarios. – DH28

+0

Gracias. Me salvó – Mohit