Encrypt/decrypt for Image on IOS

怎甘沉沦 提交于 2019-12-13 16:22:07

问题


We are working with encrypt/decrypt and UIIMAGE. If we are encrypting and decrypting and UIIMAge without save into the iphone gallery, it works fine but If we encrypt, save into the gallery, load (the image encrypted)into the app and decryting it works bad.

We are using this functions to encrypt/decrypt/save/load

//encrypt

UIImage *image = self.imageView.image;
CGContextRef ctx;
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = malloc(height * width * 4);
int valor =(height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                             bitsPerComponent, bytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast |    kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);


    NSData *data = [NSData dataWithBytes:(const void *)rawData length:sizeof(unsigned char)*valor];
   NSData *encryptedData  = [data AES256EncryptWithKey:@"\"thisIsASecre"];


rawData = [encryptedData bytes];


NSData *dataData2 = [NSData dataWithBytes:rawData length:sizeof(rawData)];

ctx = CGBitmapContextCreate(rawData,
                            CGImageGetWidth( imageRef ),
                            CGImageGetHeight( imageRef ),
                            8,
                            CGImageGetBytesPerRow( imageRef ),
                            CGImageGetColorSpace( imageRef ),
                            kCGImageAlphaPremultipliedLast );

imageRef = CGBitmapContextCreateImage (ctx);
UIImage *rawImage = [UIImage imageWithCGImage:imageRef];

self.imageView.image = rawImage;

UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);

CGContextRelease(ctx);

//decrypt

UIImage *image = self.imageView.image;
CGContextRef ctx;
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = malloc(height * width * 4);
int valor =(height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                             bitsPerComponent, bytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);


   NSData *data = [NSData dataWithBytes:(const void *)rawData length:sizeof(unsigned char)*valor];
   NSData *encryptedData  = [data AES256DecryptWithKey:@"\"thisIsASecre"];


rawData = [encryptedData bytes];




ctx = CGBitmapContextCreate(rawData,
                            CGImageGetWidth( imageRef ),
                            CGImageGetHeight( imageRef ),
                            8,
                            CGImageGetBytesPerRow( imageRef ),
                            CGImageGetColorSpace( imageRef ),
                            kCGImageAlphaPremultipliedLast );

imageRef = CGBitmapContextCreateImage (ctx);
UIImage *rawImage = [UIImage imageWithCGImage:imageRef];

self.imageView.image = rawImage;
image = rawImage;

    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);

CGContextRelease(ctx);

// Load image

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;

picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;


[self presentViewController:picker animated:YES completion:NULL];


- (void)imagePickerController:(UIImagePickerController *)picker   didFinishPickingMediaWithInfo:(NSDictionary *)info {

self.imageView.image = [info objectForKey:@"UIImagePickerControllerOriginalImage"]; 

[picker dismissViewControllerAnimated:YES completion:NULL];


}

//And the clases i use to encrypt/decrypt

- (NSData *)AES256EncryptWithKey:(NSString *)key
{
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES256+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);

size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                      keyPtr, kCCKeySizeAES256,
                                      NULL /* 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
{
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES256+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);

size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                      keyPtr, kCCKeySizeAES256,
                                      NULL /* initialization vector (optional) */,
                                      [self bytes], dataLength, /* input */
                                      buffer, bufferSize, /* output */
                                      &numBytesDecrypted);

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

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

Someone know what’s the problem?

Thxs!


回答1:


If you save a bitmap image to the photo library, it gets stored as a JPG. The lossy format of JPG will completely hose over your encryption process. Try turning your bitmap image into a PNG image and then saving that:

UIImage* pngImage = [UIImage imageWithData:UIImagePNGRepresentation(rawImage)];
UIImageWriteToSavedPhotosAlbum(pngImage, nil, nil, NULL);


来源:https://stackoverflow.com/questions/23269829/encrypt-decrypt-for-image-on-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!