本文介绍了OSX AES加密不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我需要在通过网络发送文件之前对其进行加密,而另一端则会得到解密,这是我的代码,

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

//读取NSData;
NSStringEncoding encoding = NSUTF8StringEncoding;

NSString * pFileContent = @xaaaaaaxxaaaaaax;

NSString * pKey = @01234567012345670123456701234567;


NSData * pData = [pFileContent dataUsingEncoding:encoding];

NSData * pEncryptedData = [pData AES256EncryptWithKey:pKey];


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

NSString * pDecryptedDataStr = [[NSString alloc] initWithData:decryptpted
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};
////////////// *加密* ///////////////////
- (NSData *)AES256EncryptWithKey :(NSString *)键{
//'key'应为AES256的32个字节,否则将为null-padding
char keyPtr [keySize + 1]; //用于终结器的空间(未使用)
bzero(keyPtr,sizeof(keyPtr)); //填充零(用于填充)

//获取密钥数据
[key getCString:keyPtr maxLength:sizeof(keyPtr)encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [self length];

//查看文档:对于块密码,输出大小始终小于或等于输入大小加上一个块的大小。
//这就是为什么我们需要在这里添加一个块的大小
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void * buffer = malloc(bufferSize);
char ivVector [kCCBlockSizeAES128 + 1];
//获取密钥数据
[key getCString:ivVector maxLength:sizeof(ivVector)encoding:NSUTF8StringEncoding];

bzero(ivVector,sizeof(ivVector)); //填充零(用于填充)


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


CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,kCCAlgorithmAES128,padding,
keyPtr,keySize,
ivKey / *初始化向量(可选)* /,
[self bytes],dataLength,/ * input * /
buffer,bufferSize,/ * output * /
& numBytesEncrypted);
if(cryptStatus == kCCSuccess)
{
//返回的NSData获取缓冲区的所有权,并在释放后释放它
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted] ;
}

free(buffer); //释放缓冲区
return nil;
}

- (NSData *)AES256DecryptWithKey :( NSString *)key数据:(NSData *)EncryptedData {
bool same = [self isEqualToData:EncryptedData];

//'key'应为AES256的32个字节,否则将为零填充
char keyPtr [keySize + 1]; //用于终结器的空间(未使用)
bzero(keyPtr,sizeof(keyPtr)); //填充零(用于填充)

//获取密钥数据
[key getCString:keyPtr maxLength:sizeof(keyPtr)encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [EncryptedData length];

//查看文档:对于块密码,输出大小始终小于或等于输入大小加上一个块的大小。
//这就是为什么我们需要在这里添加一个块的大小
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void * buffer = malloc(bufferSize);
const void * iv = NULL;
char ivVector [kCCBlockSizeAES128 + 1];
//获取密钥数据
[key getCString:ivVector maxLength:sizeof(ivVector)encoding:NSUTF8StringEncoding];

bzero(ivVector,sizeof(ivVector)); //填充零(用于填充)

size_t numBytesDecrypted = 0;
NSData * output_decrypt = [[NSData alloc] init];
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,kCCAlgorithmAES128,padding,
keyPtr,keySize,
ivKey / *初始化向量(可选)* /,
[加密数据字节],dataLength, * input * /
buffer,bufferSize,// bufferSize,/ * output * /
& numBytesDecrypted);
output_decrypt = [NSMutableData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
same = [self isEqualToData:output_decrypt];
if(cryptStatus == kCCSuccess)
{
//返回的NSData取得缓冲区的所有权,并在释放后释放

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

return pData;

}

free(buffer); //释放缓冲区
return nil;
}


解决方案

这是问题,

  output_decrypt = [NSMutableData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; 
same = [self isEqualToData:output_decrypt];
if(cryptStatus == kCCSuccess)
{
//返回的NSData取得缓冲区的所有权,并在释放后释放

** 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)
{
//返回的NSData取得缓冲区的所有权,并在释放后释放


return output_decrypt ;

}

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


In my application, i need to encrypt the file before sending it over the network and on the other end, it will get decrypt, This is my code,

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

}

This is working fine , only and only if Data size is 16 byte, in real time case, when i sent the file of size 151186 bytes, size of [pEncryptedData] is 15200 , and in fact size of decrypted data is same as original data,But pDecryptedDataStr is blank, any guess what is going wrong,please refer below, Encryption and decryption function,

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;
}
解决方案

Thanks for looking at this, this was the problem,

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;

    }

and solutions was;

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;

    }

Not sure, why it was causing problem, of-course i need to change return type and do some handling in the calling function to release the memory.

这篇关于OSX AES加密不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 06:01