0

在我的应用程序中,我需要在通过网络发送之前加密文件,在另一端,它将被解密,这是我的代码,

-(void)doEncryptTest:(NSString *)pFileName{

    // read the NSData; 
    NSStringEncoding encoding  =NSUTF8StringEncoding;

    NSString *pFileContent = @"xaaaaaaxxaaaaaax";

    NSString *pKey = @"01234567012345670123456701234567";


    NSData *pData = [pFileContent dataUsingEncoding:encoding];

    NSData *pEncryptedData = [pData AES256EncryptWithKey:pKey];


    NSData *decrypted=[pEncryptedData AES256DecryptWithKey:pKey Data:pEncryptedData];

    NSString* pDecryptedDataStr = [[NSString alloc] initWithData:decrypted
                                                      encoding:encoding];

}

这工作正常,仅当数据大小为 16 字节时,在实时情况下,当我发送大小为 151186 字节的文件时,[pEncryptedData] 的大小为 15200,实际上解密数据的大小与原始数据相同, 但是 pDecryptedDataStr 是空白的,猜猜怎么回事,请参考下面,加解密函数,

int keySize = kCCKeySizeAES256;
int padding = kCCOptionPKCS7Padding;
char ivKey[16]={0,0,0,0,
             0,0,0,0,
             0,0,0,0,
             0,0,0,0};
//////////////*Encryption*///////////////////
- (NSData *)AES256EncryptWithKey:(NSString *)key{
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[keySize + 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 );
    char ivVector[kCCBlockSizeAES128+1];
    // fetch key data
    [key getCString:ivVector maxLength:sizeof( ivVector ) encoding:NSUTF8StringEncoding];

    bzero( ivVector, sizeof( ivVector ) ); // fill with zeroes (for padding)


    const void *iv=NULL;
    size_t numBytesEncrypted = 0;


    CCCryptorStatus cryptStatus = CCCrypt( kCCEncrypt, kCCAlgorithmAES128, padding,
                                          keyPtr, keySize,
                                          ivKey /* 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   Data:(NSData*)EncryptedData{
    bool same =[self isEqualToData:EncryptedData];

    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[keySize+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 = [EncryptedData 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 );
    const void *iv=NULL;
    char ivVector[kCCBlockSizeAES128+1];
    // fetch key data
    [key getCString:ivVector maxLength:sizeof( ivVector ) encoding:NSUTF8StringEncoding];

    bzero( ivVector, sizeof( ivVector ) ); // fill with zeroes (for padding)

    size_t numBytesDecrypted = 0;
    NSData *output_decrypt = [[NSData alloc] init];
    CCCryptorStatus cryptStatus = CCCrypt( kCCDecrypt, kCCAlgorithmAES128, padding,
                                          keyPtr, keySize,
                                          ivKey /* initialization vector (optional) */,
                                          [EncryptedData bytes], dataLength, /* input */
                                          buffer,bufferSize ,//bufferSize, /* output */
                                          &numBytesDecrypted );
    output_decrypt = [NSMutableData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    same =[self isEqualToData:output_decrypt];
    if( cryptStatus == kCCSuccess )
    {
        //the returned NSData takes ownership of the buffer and will free it on deallocation

        NSData *pData = [[NSData alloc]initWithBytes:buffer length:numBytesDecrypted];

        return pData;

    }

    free( buffer ); //free the buffer
    return nil;
}
4

1 回答 1

0

谢谢你看这个,这是问题,

output_decrypt = [NSMutableData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    same =[self isEqualToData:output_decrypt];
    if( cryptStatus == kCCSuccess )
    {
        //the returned NSData takes ownership of the buffer and will free it on deallocation

        **NSData *pData = [[NSData alloc]initWithBytes:buffer length:numBytesDecrypted];**

        return pData;

    }

解决方案是;

output_decrypt = [NSMutableData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    same =[self isEqualToData:output_decrypt];
    if( cryptStatus == kCCSuccess )
    {
        //the returned NSData takes ownership of the buffer and will free it on deallocation


        return output_decrypt;

    }

不知道为什么会导致问题,当然我需要更改返回类型并在调用函数中进行一些处理以释放内存。

于 2012-07-31T10:52:39.327 回答