假设您在将 PDF 放到下载服务器之前以某种方式对其进行了加扰,并且应用程序在将其显示给用户之前对其进行了解扰。
然后您可以在应用中执行以下操作:
- 将加扰的 PDF 文件加载到
NSData 对象中。
- 创建一个
NSMutableData 对象并使用您选择的任何算法将您的 PDF 数据解扰到该缓冲区中。
- 现在您在内存中有一个可用的 PDF 文档,但在磁盘上只有一个加扰版本。如果您需要创建
CGPDFDocumentRef,您可以首先使用解扰后的NSMutableData 对象创建一个数据提供者,该对象通过简单的演员转换免费桥接到CFData
类似
NSMutableData *data = descrambled PDF;
CFDataRef myPDFData = (CFDataRef)data;
CGDataProviderRef provider = CGDataProviderCreateWithCFData(myPDFData);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(provider);
(该 sn-p 的功劳归this answer。)
由于应用程序必须能够对 PDF 进行解密,并且用户可以访问应用程序和加密的 PDF 文件,因此您为防止他们提取文件而采取的任何措施基本上都意味着隐蔽性安全。因此,我不会为复杂的加密算法而烦恼。您可能只需使用隐藏在应用程序二进制文件中的秘密字符串对数据进行 XOR 之类的简单操作。
要击败这种方法,攻击者需要反汇编您的二进制文件,如果有人确定您无法获胜,当前视频游戏 DRM 的悲惨状态就是明证。
顺便说一句:本着默默无闻的精神,您可能还希望将您的乱码下载的 PDF 命名为比 valuabledocument.pdf 不那么明显的名称。但它不是真正的安全。
编辑以说明异或数据:
把你乱七八糟的NSData喂给这样的东西......
// Fill this out with whatever you want. Use the same string
// and algorithm to scramble the files on the server.
static unsigned char secretString[SECRET_STRING_LENGTH];
- (NSData *)scrambleOrDescrambleData:(NSData*)input
{
unsigned char *outputBytes = malloc(input.length);
memcpy(outputBytes, input.bytes, input.length);
for (int i = 0; i < input.length; i++)
{
outputBytes[i] = outputBytes[i] ^ secretString[i % SECRET_STRING_LENGTH];
}
NSData *outputData = [[NSData alloc] initWithBytes:outputBytes length:input.length];
free(outputBytes);
return outputData;
}
XOR 的方便之处在于,执行两次会返回原始数据,因此加扰和解扰是相同的代码。
我在这里避免使用“加密”一词,因为这实际上只是对数据进行模糊处理以防止不经意的观察者看到它。