.Net和iPhone之间的AES互操作性?

我需要encryptioniPhone上的一个string,并将其发送到.Net Web服务进行解密。 我可以在iPhone上和.Net上encryption/解密,但是来自iPhone的encryptionstring不能被.Net解密。 我得到的错误是“填充无效,无法删除”。

.Net代码来自: http : //blog.realcoderscoding.com/index.php/2008/07/dot-net-encryption-simple-aes-wrapper/

iPhone代码使用以下示例代码: http : //nootech.wordpress.com/2009/01/17/symmetric-encryption-with-the-iphone-sdk/

AFAIK我的密钥设置是一样的:

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

我尝试了不同的方式来生成密文。 你好/你好:

在.Net中的e0PnmbTg / 3cT3W + 92CDw1Q ==

yrKe5Z7p7MNqx9 + CbBvNqQ ==在iPhone上

和“openssl enc -aes-128-cbc -nosalt -a -in hello.txt -pass pass:hello”生成:QA + UI + r6Zmr7yHipMcHSbQ ==

更新: 我已经在这里发布了工作代码 。

至less,您正在使用不同的初始化向量(IV)。

  • .Net代码使用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; } 

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

    这应该是: kList.Add(kRaw[(i / 8) % kRaw.Length]); 。 否则,长度为%8 == 0的密钥将重复使用相同的字母,doh!

    因此.Net使用的IV(和密钥)是: hleolhleolhleolh 。 这不是API的一部分,而是由于你指出的包装代码(它有一个严重的错误…)。

  • iPhone代码为IV使用0。

     // Initialization vector; dummy in this case 0's. uint8_t iv[kChosenCipherBlockSize]; memset((void *) iv, 0x0, (size_t) sizeof(iv)); 
  • openssl默认prepends一个随机生成的盐(这就是为什么输出更长!)。

openssl输出是更安全的,因为它预先设置了一个随机初始化向量。 它看起来像base64解码string的前几个字节是“Salted__”。 您也可以要求openssl不要使用盐(-nosalt)和/或提供IV(-iv)。

从本质上讲,openssl,.Net和iPhone使用相同的encryption,只需要小心如何使用encryption密钥和初始化向量来初始化API。

你确定你在testing中使用了相同的AES密钥吗? 你的文章中的OpenSSL例子使用了一个密码,OpenSSL派生出一个密钥和一个IV(也可能使用一个salt)。

生成一个随机的128位密钥,并以hex格式将此密钥指定给OpenSSL:

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

你不应该在任何安全的系统中使用IV = 0,但是为了testing互操作性,它是可以的。

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

·在objective-c中,从https://github.com/kelp404/CocoaSecurity添加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" }