7

我正在尝试创建我的可可应用程序的试用部分。我已经设置了所有许可(包括密钥)等。

但是我想知道如何存储例如用户第一次在安全的地方运行程序的时间,用户无法轻易找到和/或编辑它。

我对 NSUserDefaults standardUserDefaults 很感兴趣,但用户可以在 Library > Preferences 中轻松找到和编辑该数据。

4

6 回答 6

22

我反对让它变得超级安全。我们曾经有一个服务器激活,但完全没有它。以下是一些原因:

  • 即使是最“安全”的存储方式也可能被破解
  • 即使是小众产品,也可能会出现破解,无论您的方法多么安全
  • 很少,非常昂贵,非常安全的方法。其他都被破解了
  • 它违背了公平和诚实的用户,使他们更难解决导致问题的事情
  • 如果用户确实破解了您的软件或规避了您的安全性,他可能也永远不会购买它
  • 80% 的用户甚至不知道偏好文件是什么
  • 95% 的用户不考虑删除它以延长试用期的可能性
  • 一种重置试用期的简单方法可以极大地简化您对出于任何原因想要进行第二次试用的用户的支持
  • 信任用户是一个很好的卖点
  • 高级用户倾向于反对保护过多的软件

我很确定这些想法有一些例外,但极少。我想说:不要把时间浪费在注册安全上,而是给

于 2010-08-26T16:54:32.247 回答
4

您不能使用文件系统上的文件。任何想要玩弄/破解它的人都足够聪明,知道如何通过基本的标准 OSX 功能跟踪文件访问。所以一个正在添加的文件出来了。不仅如此,在卸载应用程序时创建不删除的文件也是不好的行为。人们不应该在删除您的试用应用程序后消耗资源。

如上所述,在你的捆绑包中搞乱也是一个坏主意。这为您提供了三个基本选择。

1)不要太担心。使用使用标准位置和方法的基本到期系统。您仍然可以在存储的数据中使用加密,但要知道这也会被破坏。除非您的应用完全不受欢迎,否则会发生侵犯版权的行为。

2)使用网络调用并在服务器上进行验证。这将要求应用程序始终能够访问您的服务以运行。一般来说,这不是一个好主意。如果你的服务器宕机了怎么办?如果他们离线怎么办?如果您和他们之间发生网络问题怎么办?所有这些情况都会发生。当他们这样做时,您可能会失去客户,除非您的应用程序需要连接到您的服务器才能运行(例如 Twitter 或 Facebook)。

3) 通过乱搞应用程序包或留下孤立文件来成为“坏公民”。如果您在后者中执行此操作,至少要确保它们被明确命名,以便它们与您的应用程序明显相关。

最终要记住的关键是您在用户的机器上没有安全性。这是他们的。这意味着他们可以进行物理访问,这几乎可以消除任何阻止他们挖掘的企图。你也可以这样看:你的市场越有技术意识,你就越不可能比我们所有人都聪明,你的“安全”就会被破解。如果您正在为非技术受众设计,那么您可以认为一般来说他们不会费心破解它或寻找一个。

您可以将资源用于改进应用程序,或者让自己更好地了解人们在试用期后没有使用它。其中一种可以增加您的销售额,而另一种则不会。

[编辑] 另外我应该指出,破解这些东西的最常见(如果不是最常见)方法之一是修改二进制文件。因此,通过捆绑破坏来破坏代码签名,您实际上会向该方法敞开心扉,因为您会破坏您拥有的更好的保护之一。大多数破解涉及修改二进制文件,以便执行检查的例程始终返回成功的身份验证。

于 2010-08-30T20:35:37.917 回答
3

如果必须,一种简单而常用的方法是使用嵌入在应用程序中的密钥,该密钥对磁盘上包含敏感数据的文件进行加密。挑战在于如何使密钥安全。

查看Common Crypto摘要库。

这将保护几乎所有临时用户。尽管有足够的动机,黑客可以找到一种规避方法。

于 2010-08-30T17:36:55.827 回答
3

Allan Odgaard 有一篇关于如何使用 OpenSSL 为 Cocoa 软件生成/存储许可证密钥的相当不错的文章。可能值得一读。

于 2010-09-01T16:04:16.447 回答
2

尝试将名称以句点开头的文件存储在某个文件夹中,然后设置文件的隐藏标志。

放置隐藏文件的好地方是用户文件夹(~/)底部的一个不起眼的文件,那里有很多不起眼的隐藏文件,所以很难知道哪些可以删除,哪些不能删除。示例路径:~/.xdarwinprofile或类似官方的东西。

这是一些应该可以隐藏文件的代码:

#include <assert.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <sys/attr.h>
#include <sys/errno.h>
#include <unistd.h>
#include <sys/vnode.h>

typedef struct attrlist attrlist_t;

struct FInfoAttrBuf {
    u_int32_t length;
    fsobj_type_t objType;

    union {
        char rawBytes[32];

        struct {
            FileInfo info;
            ExtendedFileInfo extInfo;
        } file;

        struct {
            FolderInfo info;
            ExtendedFolderInfo extInfo;
        } folder;
    } finderInfo;
};
typedef struct FInfoAttrBuf FInfoAttrBuf;


- (int)SetFileInvisibility:(NSString *)filePath state:(BOOL)isInvisible) {
    attrlist_t attrList;
    FInfoAttrBuf attrBuf;

    char *path = [filePath cStringUsingEncoding: NSUTF8StringEncoding];

    memset(&attrList, 0, sizeof(attrList));
    attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
    attrList.commonattr  = ATTR_CMN_OBJTYPE | ATTR_CMN_FNDRINFO;

    int err = getattrlist(path, &attrList, &attrBuf, sizeof(attrBuf), 0);
    if (err != 0)
        return errno;

    // attrBuf.objType = (VREG | VDIR), inconsequential for invisibility

    UInt16 flags = CFSwapInt16BigToHost(attrBuf.finderInfo.file.info.finderFlags);

    if (isInvisible)
        flags |= kIsInvisible;
    else
        flags &= (~kIsInvisible);

    attrBuf.finderInfo.file.info.finderFlags = CFSwapInt16HostToBig(flags);

    attrList.commonattr = ATTR_CMN_FNDRINFO;
    err = setattrlist(path, &attrList, attrBuf.finderInfo.rawBytes, sizeof(attrBuf.finderInfo.rawBytes), 0);

    return err;
}

我从这个问题的答案修改了这段代码,你可以在那里找到更多有用的信息: How to make a file invisible in Finder using objective-c

我没有测试过这段代码,但它应该可以工作。事实上,代码可能是不必要的,只需在文件名前添加一个点即可保存文件。

如果您有管理员权限,您可以对文件执行 sudo chmod 并在需要时将其设置为只读,但您不应该让您的应用程序要求用户输入密码。

于 2010-08-26T14:06:43.900 回答
0

这个解决方案对我很有效。试试这个:https ://github.com/nielsmouthaan/SecureNSUserDefaults 。它将加密的 bool/string/float/integer 存储在您的 UserDefaults 文件中。希望这是你想要的。确保下载并添加 CocoaSecurity(请参阅 SecureNSUserDefaults GitHub 页面以获取下载链接)到您的项目。CocoaSecurity 是 SecureNSUSerDefaults 的必需元素,因此您无需将其导入任何文件。您还必须下载Base64,这是 CocoaSecurity 的必需元素。您还需要将 Base64 添加到您的项目中,但不需要将其导入到您的任何文件中。

用法

在要使用加密方法的任何位置导入头文件。

#import <SecureNSUserDefaults/NSUserDefaults+SecureAdditions.h>

然后,设置一个加密密钥,可能在您的awakeFromNib方法中:

[[NSUserDefaults standardUserDefaults] setSecret:@"your_secret_goes_here"];

我建议生成一个随机的数字和字母字符串。然后,您必须将信息存储在 UserDefaults 文件中。

[[NSUserDefaults standardUserDefaults]
    setSecretObject:@"your_secret_object"
    forKey:@"the_key_your_object_will be_stored_under"];

要检索字符串,请使用以下方法:

NSString *retrievedData = [[NSUserDefaults standardUserDefaults]     
    secretStringForKey:@"the_key_your_object_will be_stored_under"];

我希望这有帮助!

于 2015-10-27T02:15:05.040 回答