【问题标题】:How to protect Digital Content (PDF) inside my iOS app?如何保护我的 iOS 应用程序中的数字内容 (PDF)?
【发布时间】:2012-06-05 11:57:59
【问题描述】:

这个问题主要是关于保护我的 iOS 应用程序中的内容。我打算制作一个可以根据用户请求下载大量内容(主要是 PDF 文件)的应用程序。下载这些 PDF 后,它们将存储在本地,以便于离线访问。

现在,我不希望任何人获取 .ipa 文件并设法提取 PDF 文件。 如果这不可能,是否有可能即使他们提取了 PDF,他们也无法查看或运行它们?

我不确定如何处理。任何建议表示赞赏。

另一种方法是,我可能会向用户提供受密码保护的文件以供下载。将关联的密码存储在 sqlite 数据库中。然后当用户从APP内部打开PDF时,应用程序会从数据库中找到密码并打开它,而不提示用户输入密码。这可能吗?怎么样?

感谢和问候

【问题讨论】:

    标签: ios pdf drm


    【解决方案1】:

    假设您在将 PDF 放到下载服务器之前以某种方式对其进行了加扰,并且应用程序在将其显示给用户之前对其进行了解扰。

    然后您可以在应用中执行以下操作:

    1. 将加扰的 PDF 文件加载到 NSData 对象中。
    2. 创建一个NSMutableData 对象并使用您选择的任何算法将您的 PDF 数据解扰到该缓冲区中。
    3. 现在您在内存中有一个可用的 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 的方便之处在于,执行两次会返回原始数据,因此加扰和解扰是相同的代码。

    我在这里避免使用“加密”一词,因为这实际上只是对数据进行模糊处理以防止不经意的观察者看到它。

    【讨论】:

    • 这种方法看起来很有希望。知道如何对 PDF 数据进行异或运算吗?
    • 查看我的编辑,了解使用字节异或的示例加扰/解扰方法。
    • 刚刚测试了答案的第一部分,效果很好!谢谢@Heiberg
    【解决方案2】:

    您可以通过加密来保护您的文件。查看Protecting Data Using On-Disk Encryption 上的苹果参考。

    【讨论】:

    • 据我所知,磁盘加密仅适用于用户使用密码锁定和解锁设备的情况。因此,如果设备解锁并且用户通过使用软件浏览文件结构来提取PDF文件,那么文件不再加密,对吗?也许我的理解是错误的,但我是这样理解的。
    • 您可以在应用程序中使用某些密钥对其进行加密,并仅在用户想要查看 PDF 时解密。
    • 嗨@igoris你能更详细地澄清一下吗?谢谢
    • @ssdesign。当您使用 AES/DES 等标准算法加密文件时,您必须提供密钥。如果您将密钥存储在钥匙串中,它将是安全的。并且您可以在用户需要时使用密钥解密您的文件。!
    【解决方案3】:

    看看这篇文章:http://aptogo.co.uk/2010/07/protecting-resources/

    作者详细介绍了加密应用程序包资源,然后将文件解密到内存中,以便只有加扰版本驻留在磁盘上。

    他们使用自定义的 NSURLProtocol 进行动态加密。很不错的总结。

    【讨论】:

      【解决方案4】:

      您不应该担心有人会获取 .ipa 文件并以这种方式提取 PDF(因为您的应用会下载 PDF 并且它们的 PDF 不附带 .ipa 文件)。

      不过,有一些工具可以让用户浏览其设备上应用程序中的文件。例如,结帐iExplorer。您应该注意,用户可能会打开任何文件——因此将密码存储在 sqlite 数据库中并不是一个好主意。使用SFHKeychainUtils 之类的方法会更安全。

      至于为 PDF 设置用户名/密码,这里有一些示例代码(您可以从 CGPDFContext Reference 了解更多信息):

      NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: @"letMeIn", kCGPDFContextOwnerPassword, @"r3adm3", kCGPDFContextUserPassword, nil];
      [myPDFDocument writeToFile: @"/some/path" withOptions: options];
      

      我还建议将加密文件存储在磁盘上。您可以使用NSData+AES 来执行此操作。这是NSData+AES 的另一个实现。从磁盘读取时,您可以将未加密的 NSData 保存在内存中并从中显示 PDF,而不是从磁盘读取未加密的 PDF。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-30
        • 1970-01-01
        相关资源
        最近更新 更多