AES compatibility between .Net and iPhone?

I need to encrypt the string on the iPhone and send it to the .Net web service for decryption. I can encrypt / decrypt on iPhone and with .Net, but encrypted strings from iPhone cannot be decrypted .Net. The error I get is "Filling is invalid and cannot be deleted."

.Net Code: http://blog.realcoderscoding.com/index.php/2008/07/dot-net-encryption-simple-aes-wrapper/

The iPhone code uses the sample code: http://nootech.wordpress.com/2009/01/17/symmetric-encryption-with-the-iphone-sdk/

AFAIK my key settings are the same:

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

I tried different ways to generate ciphertext. hello / hello:

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

yrKe5Z7p7MNqx9 + CbBvNqQ == on iPhone

and "openssl enc -aes-128-cbc -nosalt -a -in hello.txt -pass pass: hello" generates: QA + Ul + r6Zmr7yHipMcHSbQ ==

Update: I posted the working code here .

+21
iphone encryption aes
Feb 11 '09 at 19:40
source share
3 answers

At least you are using different initialization vectors (IV).

  • The .Net code uses the key for 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; } 

    and

     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; } 

    which should be: kList.Add(kRaw[(i / 8) % kRaw.Length]); . Otherwise, a key whose length is% 8 == 0 will use the same letter, doh!

    So the IV (and key) used by .Net: hleolhleolhleolh . This is not part of the API, but rather because of the wrapper code you pointed to (which has a serious error in it ...).

  • IPhone uses code 0 for IV.

     // Initialization vector; dummy in this case 0's. uint8_t iv[kChosenCipherBlockSize]; memset((void *) iv, 0x0, (size_t) sizeof(iv)); 
  • openssl by default adds randomly generated salt (so the output is longer!).

The openssl output is more secure as it adds a random initialization vector. It looks like the first few bytes of the base64 decoded string are "Salted__". You can also ask openssl not to use salt (-nosalt) and / or provide IV (-iv).

Essentially, openssl, .Net and iPhone use the same encryption, you just need to be careful how you initialize the API with the encryption key and the initialization vector.

+16
Feb 12 '09 at 3:44
source share
β€” -

Are you sure you use the same AES keys in your tests? In the OpenSSL example, your message uses a password that OpenSSL infers the key and IV from (and probably also uses salt.

Create a random 128-bit key and specify this key in hexadecimal format in OpenSSL with:

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

You should not use IV = 0 on any secure system, but this is normal for compatibility testing.

+2
Feb 12 '09 at 6:58
source share

In 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; } } 

. In objective-c add the CocoaSecurity library from 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" } 
+2
Dec 11 '15 at 1:11
source share



All Articles