问题描述
在我的应用程序中,我需要在通过网络发送文件之前对其进行加密,而另一端则会得到解密,这是我的代码, - (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加密不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!