如何解密在PHP中加密的Objective C / IOS中的文件?

我用Google搜索过多的错误,但没有发现任何有用的东西。 我正在使用以下代码获取在php中加密的文件:

mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateencryptkey, base64_encode(file), MCRYPT_MODE_CBC, $hardvector); 

我无法在IOS中解密它。 我曾经尝试过很多库,比如NSDATA + CommonCrypto,NSFileManager-AES,NSDATA-aes,但是我没有成功解密文件。

以下是使用的Objective-C代码:

 - (NSData *)AESDecryptWithPassphrase:(NSString *)pass { NSMutableData *ret = [NSMutableData dataWithCapacity:[self length]]; unsigned long rk[RKLENGTH(KEYBITS)]; unsigned char key[KEYLENGTH(KEYBITS)]; const char *password = [pass UTF8String]; for (int i = 0; i < sizeof(key); i++) key[i] = password != 0 ? *password++ : 0; int nrounds = rijndaelSetupDecrypt(rk, key, KEYBITS); unsigned char *srcBytes = (unsigned char *)[self bytes]; int index = 0; while (index < [self length]) { unsigned char plaintext[16]; unsigned char ciphertext[16]; int j; for (j = 0; j = [self length]) break; ciphertext[j] = srcBytes[index++]; } rijndaelDecrypt(rk, nrounds, ciphertext, plaintext); [ret appendBytes:plaintext length:sizeof(plaintext)]; } return ret; } 

此代码适用于文本但无法解密文件。 当我保存解密的文件然后它说文件系统错误。 那些解密的文件无法在任何系统上打开,我认为文件格式在此过程中受到干扰。

我也尝试了以下代码,但没有成功:

 - (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm key: (id) key // data or string initializationVector: (id) iv // data or string options: (CCOptions) options error: (CCCryptorStatus *) error { CCCryptorRef cryptor = NULL; CCCryptorStatus status = kCCSuccess; NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]); NSParameterAssert(iv == nil || [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]); NSMutableData * keyData, * ivData; if ( [key isKindOfClass: [NSData class]] ) keyData = (NSMutableData *) [key mutableCopy]; else keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy]; if ( [iv isKindOfClass: [NSString class]] ) ivData = [[iv dataUsingEncoding: NSUTF8StringEncoding] mutableCopy]; else ivData = (NSMutableData *) [iv mutableCopy]; // data or nil [keyData autorelease]; [ivData autorelease]; // ensure correct lengths for key and iv data, based on algorithms FixKeyLengths( algorithm, keyData, ivData ); status = CCCryptorCreate( kCCDecrypt, algorithm, options, [keyData bytes], [keyData length], [ivData bytes], &cryptor ); if ( status != kCCSuccess ) { if ( error != NULL ) *error = status; return ( nil ); } NSData * result = [self _runCryptor: cryptor result: &status]; if ( (result == nil) && (error != NULL) ) *error = status; CCCryptorRelease( cryptor ); return ( result ); } 

上面代码的第二个function:

 - (NSData *) _runCryptor: (CCCryptorRef) cryptor result: (CCCryptorStatus *) status { size_t bufsize = CCCryptorGetOutputLength( cryptor, (size_t)[self length], true ); void * buf = malloc( bufsize ); size_t bufused = 0; size_t bytesTotal = 0; *status = CCCryptorUpdate( cryptor, [self bytes], (size_t)[self length], buf, bufsize, &bufused ); if ( *status != kCCSuccess ) { free( buf ); return ( nil ); } bytesTotal += bufused; // From Brent Royal-Gordon (Twitter: architechies): // Need to update buf ptr past used bytes when calling CCCryptorFinal() *status = CCCryptorFinal( cryptor, buf + bufused, bufsize - bufused, &bufused ); if ( *status != kCCSuccess ) { free( buf ); return ( nil ); } bytesTotal += bufused; return ( [NSData dataWithBytesNoCopy: buf length: bytesTotal] ); } 

我一周都没能解决这个问题……

需要注意的一件事是mcrypt_encrypt的文件参数,看起来该文件在加密之前是进行了base64编码(不是没有任何意义),这意味着你必须在解密后进行base64解码。

其他参数很简单:
MCRYPT_RIJNDAEL_128是AES,128位,128位密钥
MCRYPT_MODE_CBC是cbc模式,是CommonCrypto的默认模式。
块大小的填充是空字符,而非标准,因此非填充长度可能是个问题。

不是你需要另一种AES方法,这是我使用的方法:

 #import  + (NSData *)doCipher:(NSData *)dataIn iv:(NSData *)iv key:(NSData *)symmetricKey context:(CCOperation)encryptOrDecrypt { CCCryptorStatus ccStatus = kCCSuccess; size_t cryptBytes = 0; // Number of bytes moved to buffer. NSMutableData *dataOut = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128]; ccStatus = CCCrypt( encryptOrDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, symmetricKey.bytes, kCCKeySizeAES128, iv.bytes, dataIn.bytes, dataIn.length, dataOut.mutableBytes, dataOut.length, &cryptBytes); if (ccStatus != kCCSuccess) { NSLog(@"CCCrypt status: %d", ccStatus); } dataOut.length = cryptBytes; return dataOut; } // Also add Security.framework to your project. 

请注意,它期望NSData输入,并且填充被指定为标准PKCS。

请参见CommonCryptor.h