为什么iPad上的AESencryption和PHP解密失败?

我有一个iPad应用程序,它将encryption的信息传输到基于PHP的网站,但是我很难正确解密这些信息。 我使用下面的代码进行PHP端解密:

//Decryption function function mc_decrypt($decrypt, $key, $iv) { $decoded = base64_decode($decrypt); $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, ''); mcrypt_generic_init($td, $key, $iv); $decrypted = mdecrypt_generic($td, $decoded); mcrypt_generic_deinit($td); mcrypt_module_close($td); return trim($decrypted); } 

和我的iPad应用程序中的这个Objective-C代码:

 #import <CommonCrypto/CommonCryptor.h> @implementation NSData (AES256) - (NSData *)AES256EncryptWithKey:(NSString *)key { // 'key' should be 32 bytes for AES256, will be null-padded otherwise char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) // fetch key data [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; //See the doc: For block ciphers, the output size will always be less than or //equal to the input size plus the size of one block. //That's why we need to add the size of one block here size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES256, NULL /* initialization vector (optional) */, [self bytes], dataLength, /* input */ buffer, bufferSize, /* output */ &numBytesEncrypted); if (cryptStatus == kCCSuccess) { //the returned NSData takes ownership of the buffer and will free it on deallocation return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; } free(buffer); //free the buffer; return nil; } - (NSData *)AES256DecryptWithKey:(NSString *)key { // 'key' should be 32 bytes for AES256, will be null-padded otherwise char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) // fetch key data [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; //See the doc: For block ciphers, the output size will always be less than or //equal to the input size plus the size of one block. //That's why we need to add the size of one block here size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesDecrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES256, NULL /* initialization vector (optional) */, [self bytes], dataLength, /* input */ buffer, bufferSize, /* output */ &numBytesDecrypted); if (cryptStatus == kCCSuccess) { //the returned NSData takes ownership of the buffer and will free it on deallocation return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; } free(buffer); //free the buffer; return nil; } @end 

为什么当我尝试解密在iPad上编码的数据并在PHP端进行解密时,我看到数据损坏?

检查您正在使用的密钥。 在PHP中,MCRYPT_RIJNDAEL_128_256等常量不代表关键的强度,而是代表使用的块大小。

要使用PHP获得128位encryption,您需要使用长度为16个字节的密钥。 对于256你需要32个字节等等等等。

PHP和C代码对我来说都是正确的。 确保在这两种情况下钥匙的使用都是正确的。

作为另一个想法。 它看起来像你在C中使用PKCS#7填充。我不相信PHP的devise默认情况下使用该填充。 如果内存服务于我,我相信Mcrypt函数使用null填充。

最后在PHP中检查你的初始化向量。 我注意到你没有在你的C代码中使用它,这意味着你不应该接受PHP中的$ ivvariables。 这应该作为NULL传递到mcrypt函数(但这是非常不鼓励)。

你应该做的是随机化你的C代码(数据被encryption的地方),然后把IV和encryption的数据一起发送。 您可以检测正在使用的algorithm的IV的大小,并将其从encryption数据的前面分离出来,然后用来填充您的PHP方面的东西。 这进一步确保您的encryption。

请参考此讨论以获得更好的使用情况AESencryption/解密使用CommonCrypto的AES使用太多内存 – Objective-C