Encryption of videos using RNCryptor inside the iOS application?

584 views
Skip to first unread message

adil imran

unread,
May 27, 2016, 1:45:34 PM5/27/16
to rncryptor
I am building an application which have the paid tutorials videos. The videos are not hosted on any kind of server instead they are part of my application bundle. I want to make sure that those videos cannot be extracted from my bundle. Can I use the RNCryptor to encrypt the videos and in the application and decrypt only while playing? 
Please guide me if some one knows any good method for encryption in my case.

Rob Napier

unread,
May 27, 2016, 1:56:42 PM5/27/16
to rncr...@googlegroups.com
This is not in general a solvable problem. If you distribute the data along with an encryption key to attackers, it will always be possible for them to decrypt the data. Trying to stop that is just obfuscation. DRM is a constant arms race. You obfuscate, they break it, you obfuscate a different way, they break it, you try to make it hard to run debuggers, they work around that, you hide the obfuscation code, they find it. If you must do that, fine, but it is a never-ending effort that you must assign ongoing resources to fixing every time they break it.

That said, RNCryptor is not designed for streaming video. See https://github.com/RNCryptor/RNCryptor#does-rncryptor-support-random-access-decryption. I've considered building a framework that would encrypt video well, but RNCryptor isn't that framework.

-Rob


On Sun, May 22, 2016 at 2:13 PM, adil imran <adilim...@gmail.com> wrote:
I am building an application which have the paid tutorials videos. The videos are not hosted on any kind of server instead they are part of my application bundle. I want to make sure that those videos cannot be extracted from my bundle. Can I use the RNCryptor to encrypt the videos and in the application and decrypt only while playing? 
Please guide me if some one knows any good method for encryption in my case.

--
You received this message because you are subscribed to the Google Groups "rncryptor" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rncryptor+...@googlegroups.com.
Visit this group at https://groups.google.com/group/rncryptor.
For more options, visit https://groups.google.com/d/optout.



--
Rob Napier
Cocoaphony blog -- http://robnapier.net/blog
iOS Programming Pushing the Limits -- http://robnapier.net/book

Udo Thiel

unread,
May 27, 2016, 2:09:40 PM5/27/16
to rncryptor
I'm currently investigating this problem as well using AVPlayer for playback, which, at first glance at least, requires a file URL, which in turn would require your app to decrypt your video onto disk which of course makes the whole encryption business obsolete.

There is, however, a machanism in AVPlayer specifically for playing back encrypted/DRM'd video using the AVAssetResourceLoaderDelegate, which works with NSData instead of file URLs which may work if we can hold the whole video in memory or maybe use memory mapped I/O. I'm having some other issues right now and will report back if I find a solution. SO and the internet in general are rather sparse on this subject :-(

Udo Thiel

unread,
May 30, 2016, 6:46:04 AM5/30/16
to rncryptor
So it is possible to do the decryption in memory using the AVAssetResourceLoaderDelegate:


// somewhere in your code, probably -viewDidLoad:
       
NSURL *dummyURL         = [NSURL URLWithString:@"somethingfunny://dummy.mov"];// a non-reachable URL will force the use of the resourceLoader delegate

       AVURLAsset *asset       = [AVURLAsset assetWithURL:dummyURL];

       [asset.resourceLoader setDelegate:self queue:dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)];

       AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];

       self.avPlayerVC.player = [AVPlayer playerWithPlayerItem:item];

       [self.avPlayerVC.player play];


//

- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {


        loadingRequest.contentInformationRequest.contentType    = [NSString ut_UTTypeQuickTimeMovie];

      loadingRequest.contentInformationRequest.contentLength  = self.doc.decryptedAsset.length;

      loadingRequest.contentInformationRequest.byteRangeAccessSupported       = YES;


        NSRange range = NSMakeRange((NSUInteger)loadingRequest.dataRequest.requestedOffset, loadingRequest.dataRequest.requestedLength);

       [loadingRequest.dataRequest respondWithData:[self.doc.decryptedAsset subdataWithRange:range]];


        [loadingRequest finishLoading];

return YES;

}



// in your model class:

// cache decrypted data, otherwise memory consumption would be 4x the asset size

- (NSData *)decryptedAsset {

if (!self.asset.fileURL) {

[_errh logMessage:@"Warning: nil asset" object:self alertUser:NO];

return nil;

} else if (!_decryptedAsset) {

TSCryptoKeys *ckeys = [TSCryptoKeys userCryptoKeys];

NSError *error;

// by using the NSDataReadingMappedAlways option the property doesn't consume any memory at all

// decryption itself appears to be consuming 2x asset size memory once

NSData *encData = [NSData dataWithContentsOfURL:self.asset.fileURL options:NSDataReadingMappedAlways error:&error];

[_errh handleError:error];

_decryptedAsset = [ckeys decryptData:encData];

}

return _decryptedAsset;

}



sup...@ivoapplication.com

unread,
Jun 22, 2016, 7:25:01 AM6/22/16
to rncryptor
Take a look here PrivatePlayer 
Do you need a build-in solution for your application? Send me a message. PrivatePlayer will be available at Apple Store (review was already done), very soon. The encryption / decryption engine is specially designed to support encryption while playing (a random access is supported) and there is never any part of the video in unencrypted form on user's device. The video is payable only on devices own by the user. Video can be safely transported to user's device by an email or by any other public way.

nishabe

unread,
Jan 21, 2017, 5:23:14 PM1/21/17
to rncryptor
Hello Udo Thiel,
Do you have a github repo where I can have a look at the below implementation in detail?

Thanks.
Reply all
Reply to author
Forward
0 new messages