Pregunta

necesito para cifrar una cadena en el iPhone y enviarla a un servicio web .Net para el descifrado. Soy capaz de cifrar / descifrar en el iPhone y con .Net, pero las cadenas cifradas desde el iPhone no puede ser descifrado por .Net. El error que consigo es "El relleno es válido y no se puede quitar."

El código .Net es de: http: //blog.realcoderscoding. com / index.php / 2008/07 / punto-net-cifrado-simples-aes-envoltura /

El código iPhone utiliza el código de ejemplo: http://nootech.wordpress.com/2009/01/17/symmetric-encryption-with-the-iphone-sdk/

Que yo sepa mi configuración clave son los mismos:

result.BlockSize = 128; // iPhone: kCCBlockSizeAES128
result.KeySize = 128; // kCCBlockSizeAES128
result.Mode = CipherMode.CBC;
result.Padding = PaddingMode.PKCS7; // kCCOptionPKCS7Padding

He intentado diferentes maneras de generar el texto cifrado. hola / hola es:

e0PnmbTg / 3cT3W + 92CDw1Q == en .Net

yrKe5Z7p7MNqx9 + == CbBvNqQ en iPhone

y "-aes-128-cbc enc openssl -nosalt -a -en Hello.txt -pass pasar: hello" genera: QA + Ul + r6Zmr7yHipMcHSbQ ==

Actualización: He publicado el código de trabajo para este aquí.

¿Fue útil?

Solución

Por lo menos, está utilizando diferentes vectores de inicialización (IV).

  • El código .Net utiliza la clave para IV.

    private static AesCryptoServiceProvider GetProvider(byte[] key)
    {
        //Set up the encryption objects
        AesCryptoServiceProvider result = new AesCryptoServiceProvider();
        byte[] RealKey = Encryptor.GetKey(key, result);
        result.Key = RealKey;
        result.IV = RealKey;
        return result;
    }

    y

    private static byte[] GetKey(byte[] suggestedKey, AesCryptoServiceProvider p)
    {
        byte[] kRaw = suggestedKey;
        List kList = new List();
        for (int i = 0; i < p.LegalKeySizes[0].MinSize; i += 8 )
        {
            kList.Add(kRaw[i % kRaw.Length]);
        }
        byte[] k = kList.ToArray();
        return k;
    }

    lo que probablemente debería ser: kList.Add(kRaw[(i / 8) % kRaw.Length]);. De lo contrario una tecla cuya longitud 8% == 0 usará la misma letra repetida, do!

    Así, el IV (y clave) utilizado por .Net es: hleolhleolhleolh. Esto no es parte de la API, sino más bien debido al código de contenedor que usted ha señalado en (que tiene un grave error en el que ...).

  • El código iPhone utiliza 0 para IV.

    // Initialization vector; dummy in this case 0's.
    uint8_t iv[kChosenCipherBlockSize];
    memset((void *) iv, 0x0, (size_t) sizeof(iv));
  • openssl por defecto antepone una sal generada de forma aleatoria (que es la razón por la salida es más largo!).

La salida openssl es más seguro ya que está anteponiendo un vector de inicialización aleatorio. Parece que los primeros bytes de la base 64 decodificados cadena es "Salted__". También puede pedir a OpenSSL para no utilizar una sal (-nosalt) y / o proporcionar una vía intravenosa (a iv).

En esencia, openssl, .Net, y el iPhone están utilizando el mismo cifrado, sólo tiene que tener cuidado de cómo inicializar las API con la clave de cifrado y el vector de inicialización.

Otros consejos

En C #

void test(){
   string ctB64 = encrypt("hola");
   Console.WriteLine(ctB64);  // the same as in objective-c
}

string encrypt(string input)
        {
            try
            {
                // Create a new instance of the AesManaged class.  This generates a new key and initialization vector (IV).
                AesManaged myAes = new AesManaged();

                // Override the cipher mode, key and IV
                myAes.Mode = CipherMode.CBC;
                myAes.IV = new byte[16] { 0x10, 0x16, 0x1F, 0xAD, 0x10, 0x10, 0xAA, 0x22, 0x12, 0x51, 0xF1, 0x1E, 0x15, 0x11, 0x1B, 0x10 }; // must be the same as in objective-c
                myAes.Key = Encoding.UTF8.GetBytes(“0123456789123456”);
                //CipherKey;  // Byte array representing the key
                myAes.Padding = PaddingMode.PKCS7;

                // Create a encryption object to perform the stream transform.
                ICryptoTransform encryptor = myAes.CreateEncryptor();

                // perform the encryption as required...
                MemoryStream ms = new MemoryStream();
                CryptoStream ct = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
                byte[] binput = Encoding.UTF8.GetBytes(input);
                ct.Write(binput, 0, binput.Length);
                ct.Close();
                byte [] result = ms.ToArray();
                return Convert.ToBase64String(result);
            }
            catch (Exception ex)
            {
                // TODO: Log the error 
                Console.WriteLine(ex);
                throw ex;
            }

        }

· En Objective-C, Agregar biblioteca CocoaSecurity de https://github.com/kelp404/CocoaSecurity

#import "CocoaSecurity.h"
#import "Base64.h"

…

- (void) test{
 unsigned char bytes[] = { 0x10, 0x16, 0x1F, 0xAD, 0x10, 0x10, 0xAA, 0x22, 0x12, 0x51, 0xF1, 0x1E, 0x15, 0x11, 0x1B, 0x10 }; // must be the same as in c#

    NSData *iv = [NSData dataWithBytesNoCopy:bytes length:16 freeWhenDone:YES];
    NSData* key =   [@"0123456789123456" dataUsingEncoding:NSUTF8StringEncoding];

    CocoaSecurityResult *result = [CocoaSecurity aesEncrypt:@"hola" key:key iv:iv];
   NSLog(@"%@", result.base64); // the same as in c#


    NSData *data = [NSData dataWithBase64EncodedString:result.base64];
    CocoaSecurityResult *result2 = [CocoaSecurity aesDecryptWithData:data key:key iv:iv];

    NSLog(@"%@", result2.utf8String); // show "hola"

}

¿Está seguro de que está utilizando la misma clave AES en sus pruebas? El ejemplo OpenSSL en su entrada utiliza una contraseña que OpenSSL deriva una clave y una IV de (y probablemente usa una sal también.

Generar una clave aleatoria de 128 bits y especificar esta clave en formato hexadecimal para OpenSSL con:

openssl enc -aes-128-cbc -a -in hello.txt -K KEY_IN_HEX -iv 0

Usted no debe usar IV = 0 en cualquier sistema seguro, pero para las pruebas de interoperabilidad que está bien.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top