如何解密在PHP中加密的Objective C / IOS中的文件? [英] How to decrypt a file in Objective C/IOS that is encrypted in php?

查看:93
本文介绍了如何解密在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,但我没有成功解密文件。



以下是目标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]; (int i = 0; i< sizeof(key); i ++)
key [i] = password!= 0? *密码++: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< sizeof(ciphertext); j ++)
{
if(index> = [self length])
break;

ciphertext [j] = srcBytes [index ++];
}
rijndaelDecrypt(rk,nrounds,ciphertext,plaintext);
[ret appendBytes:plaintext length:sizeof(plaintext)];

}
return ret;
}

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



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

   - (NSData *)decryptptedDataUsingAlgorithm:(CCAlgorithm)算法
key:(id)key //数据或字符串
(CCOptions)选项
错误:(CCCryptorStatus *)错误
{
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];

//确保密钥和iv数据的正确长度,基于算法
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);
}

上面的第二个函数代码:


$ b code code code code code code code code code code code code $ )[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;

//从Brent Royal-Gordon(Twitter:architechies):
//调用CCCryptorFinal()时需要更新buf ptr过去的字节
* 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< CommonCrypto / CommonCryptor.h> 

+(NSData *)doCipher:(NSData *)dataIn
iv:(NSData *)iv
key:(NSData *)symmetricKey
上下文:(CCOperation )encryptOrDecrypt
{
CCCryptorStatus ccStatus = kCCSuccess;
size_t cryptBytes = 0; //移动到缓冲区的字节数。
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;
}
//还要将Security.framework添加到你的项目中。

请注意,它希望NSData输入和填充被指定为标准PKCS。



请参阅 CommonCryptor.h


I have googled too much for this error but found nothing useful. I am getting a file that is encrypted in php using the following code:

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

I am unable to decrypt it in IOS. I had tried many libraries like NSDATA+CommonCrypto, NSFileManager-AES, NSDATA-aes but i have not got success in decrypting the file.

Following is the objective-C code used:

- (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 < sizeof(ciphertext); j++)
        {
            if (index >= [self length])
                break;

            ciphertext[j] = srcBytes[index++];
        }
        rijndaelDecrypt(rk, nrounds, ciphertext, plaintext);
        [ret appendBytes:plaintext length:sizeof(plaintext)];

    }
    return ret;
}

This code works well for text but unable to decrypt files. When i save the decrypted files then it says the file system error. Those decrypted files cannot be opened on any system, i think the file format is disturbed in the process.

I also tried the following code but no success:

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

2nd function from above code:

- (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] );
}

I haven't been able to solve this for a week...

解决方案

One thing to note is the file parameter to mcrypt_encrypt, it appears that the file is being base64 encoded prior to encryption (not that it makes any sense), that would imply you would have to base64 decode after decryption.

The other parameters are straight forward:
MCRYPT_RIJNDAEL_128 is AES, 128 with a 128 bit key
MCRYPT_MODE_CBC is cbc mode, the default for CommonCrypto.
The padding to block size is with null characters, rather nonstandard so the non-padded length may be a problem.

Not that you need yet another AES method, this is the one I use:

#import <CommonCrypto/CommonCryptor.h>

+ (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.

Note that it expects NSData input and the padding is specified as standard PKCS.

See CommonCryptor.h

这篇关于如何解密在PHP中加密的Objective C / IOS中的文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆