OSX AES加密不工作 [英] OSX AES Encryption is not working

查看:156
本文介绍了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加密不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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