2009-10-28 15 views
16

he estado rompiendo mi pelo todo el día tratando de resolver este ...diferencia entre el iPhone AES (Objetivo-c) y Java

que tienen un cliente de Objective-C se ejecuta en el iPhone, que conecta a una aplicación Java servidor. El iPhone está encriptando datos usando AES, pero no puedo descifrarlo en el servidor. Estoy usando una contraseña y un mensaje conocidos (cadena única) y estoy generando la matriz de bytes en el iPhone, generando una matriz de bytes de comparación en el servidor Java usando la misma clave y el mismo mensaje pero las matrices de bytes son completamente diferentes (y por lo tanto no ser decodificado en el lado de Java).

el cliente está utilizando la biblioteca CommonCrypto con los siguientes valores ...

de datos es un NSData sosteniendo el "mensaje" palabra utilizando dataUsingEncoding:NSASCIIStringEncoding Key es una NSData la celebración de la frase "1234567891123456" de nuevo utilizando la codificación como encima. algoritmo es kCCAlgorithmAES128 Options es kCCOptionsPKCS7Padding (que creo que equivale a BCE en el servidor ?!)

el servidor está usando el siguiente código ...

byte[] key = "1234567891123456".getBytes(); 
Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding"); 

SecretKeySpec k = new SecretKeySpec(key, "AES"); 
c.init(Cipher.ENCRYPT_MODE, k); 
byte[] encryptedData = c.doFinal("message".getBytes()); 

pero los datos en encryptedData no coincide lo que se está generando en el código objetivo-c, las matrices de bytes son completamente diferentes.

¿Alguien puede ver algo obvio que estoy haciendo mal? Yo creo los ajustes son todos iguales ... :(

  • ACTUALIZACIÓN - Conforme a lo solicitado ....

autorización así que aquí va ....

cliente de iPhone es cifrar el siguiente "mensaje" cadena utiliza la tecla "1234567891123456" se utiliza un vector de inicialización de "1010101010101010" está utilizando AES128, con el modo CBC (por lo que puedo decir) y las opciones de kCCOptionsPKCS7Padding.

El resultado de la encriptación (con codificación base64) es UHIYllDFAXl81ZM7OZPAuA ==

El servidor está cifrar la misma cadena, con el mismo vector de llave y la inicialización. Está utilizando el siguiente Cipher.getInstance ("AES/CBC/PKCS5Padding");

El resultado de la encriptación (con codificación base64) es ALBnFIHysLbvAxjvtNo9vQ ==

Gracias.

  • ACTUALIZACIÓN 2 - Conforme a lo solicitado ...

Aquí está el código iPhone ....

NSData *toencrypt = [@"message" dataUsingEncoding:NSASCIIStringEncoding]; 

NSData *pass = [@"1234567891123456" dataUsingEncoding:NSASCIIStringEncoding]; 

NSData *iv = [@"1010101010101010" dataUsingEncoding:NSASCIIStringEncoding];  

CCCryptorStatus status = kCCSuccess; 

NSData *encrypted = [toencrypt dataEncryptedUsingAlgorithm:kCCAlgorithmAES128 key:pass initializationVector:iv options:kCCOptionPKCS7Padding error:&status]; 

NSString *text = [NSString base64StringFromData:encrypted length:[encrypted length]]; 

La categoría NSData para cifrar viene de aquí ...

http://github.com/AlanQuatermain/aqtoolkit/tree/master/CommonCrypto/

Por cierto, he comprobado las matrices de bytes que se encuentran en toencrypt, pasar y IV y que coinciden con los que están en el servidor.

+0

He cambiado el servidor para usar ECB como se sugiere y todavía no funciona. Por cierto, sí noté que el servidor usa PKCS5 y el cliente usa PKCS7, pero no hay 5 disponibles en el cliente y no hay 7 disponibles en el servidor, y aparentemente son compatibles de todos modos. –

+0

Sí, el relleno de PKCS7 es igual que PKCS5Padding. Si cambiar al ECB no funcionó, es probable que el iPhone esté usando el modo CBC. Debe determinar el vector de inicialización y asegurarse de que el servidor esté utilizando el mismo. – erickson

+0

Gracias por las respuestas. Creé un IV igual en el cliente y en el servidor pero aún no funcionaba. ¡Aquí es donde una biblioteca de AES decente y decente para el iPhone está muy ausente! :( –

Respuesta

3

Esta no es mi área pero parece que en el cliente tiene PKCS7 pero en el servidor tiene PKCS5.

+0

A partir de [wikipedia] (http://en.wikipedia.org/wiki/Padding_%28cryptography%29), los modos son intercambiables. – lupz

2

¿Qué modo usa el iPhone con AES? No enumera nada, así que quizás eso signifique que no usa encadenamiento (BCE).

Sin embargo, en el lado de Java, está utilizando CBC, pero no especifica un vector de inicialización. Eso es definitivamente incorrecto. Si realmente está utilizando CBC, tiene para tener el IV que se utilizó durante el cifrado. El IV no es secreto; se puede enviar junto con el texto cifrado.

Si realmente está utilizando ECB, no hay IV, pero su Java especifica el modo incorrecto.

0

Según sus muestras, el servidor lo está haciendo bien y el cliente no.

Al ver los datos, supongo que la clave es incorrecta. Por favor, muéstrenos el código del iPhone, especialmente el código para ir desde "1234567891123456" a su clave.

+0

Agregado a la publicación original según lo solicitado. –

0

Recientemente me encontré con esto en otro proyecto. El problema era que la clave era un byte demasiado larga para caber en el buffer char dentro del método dataEncryptedUsingAlgorithm.

El problema era que el método getBytes en el NSString tenía errores. Copiaría la mayor parte de la cadena en el búfer, pero como la clave era un byte demasiado larga, "marcaría" la operación como fallida configurando el primer carácter en NUL (char 0).

Ingrese a ese método en Xcode y vea cómo se ve su búfer clave char [16]. Puede tener el mismo problema y tener el contenido { 0, '2', '3', '4', ... }.

3

Acabo de encontrar el mismo problema. Estoy usando CommonCrypto en el cliente iOS, utilizando la configuración:

NSData * encrypted = [data dataEncryptedUsingAlgorithm:kCCAlgorithmAES128 key:pass initializationVector:iv options:kCCOptionPKCS7Padding error:&status]; 

El servidor utiliza Cipher.getInstance("AES/CBC/PKCS5Padding"); con el mismo vector de inicialización y clave que el cliente.

Después golpeando mi cabeza contra la pared durante las últimas horas, finalmente siguió el consejo de Jason y comprueba la rutina dataEncryptedUsingAlgorithm e imprime keyData justo después FixKeyLengths. Resulta que mi clave de 128 bits se extendió a 192 bits con 0 añadidos al final. Después de arreglar esto, todo funciona correctamente. :)

Actualización: Mi respuesta fue publicada hace casi 2 años, y este problema parece corregido en el último código NSData+CommonCrypto. En concreto, esta era la parte que causó el problema:

static void FixKeyLengths(CCAlgorithm algorithm, NSMutableData * keyData, NSMutableData * ivData) 
{ 
    NSUInteger keyLength = [keyData length]; 
    switch (algorithm) 
    { 
    case kCCAlgorithmAES128: 
    { 
     if (keyLength <= 16) 
     { 
     [keyData setLength: 16]; 
     } 
     else if (keyLength <= 24) 
     { 
     [keyData setLength: 24]; 
     } 
     else 
     { 
     [keyData setLength: 32]; 
     } 

     break; 
    } 

El primer cheque keyLength <= 16 no existía antes.

Si todavía tiene problemas ahora, probablemente sea otra cosa.

+0

Hola, tengo el mismo problema, ¿pueden compartir el código de muestra? Gracias. –

+0

@ylian: estoy enfrentando el mismo problema. Por favor comparte tu código. –

Cuestiones relacionadas