2010-08-13 61 views
7

我正在尝试创建我的可可应用程序的试用版。我有所有设置的许可(包括键)等如何用目标C安全地存储数据? (Mac/Cocoa Dev)

但我想知道如何我可以存储,例如第一次用户在安全的地方运行程序,用户不能轻易找到它, /或编辑它。

我有一个NSUserDefaults standardUserDefaults的小提琴,但用户可以很容易地在库>首选项中查找和编辑这些数据。

+0

将其存储在应用程序捆绑包中可能会稍微难以让用户绕过。这取决于你想要保护的有多好。 – David 2010-08-13 08:58:50

+0

它得是相当不错的,因为我不希望用户能够使用应用程序的试用期结束 – Daniel 2010-08-13 08:59:38

+0

在我毕竟只是看着NSUserDefaults的encodeObject:forKey:,也许他们会是足够的? – Daniel 2010-08-13 09:00:13

回答

21

我会反对让它超级安全。我们曾经有一个服务器激活,但完全离开它。下面是一些原因:

  • 即使是最“安全”的存储方法可以打破
  • 即使是小众产品的裂缝可能被开发,没有办法解决,不管如何保护你的方法
  • 有很少,非常昂贵,非常安全的方法。所有的人都被破解
  • 它违背了公平和诚实的用户,使得他们更难解决的事情造成的问题
  • 如果用户确实破解软件或绕过您的安全,他很可能也永远不会有买了它的用户
  • 80%,甚至不知道偏好文件是什么
  • 所有用户的
  • 95%的人不认为的可能性,将其删除,以延长试用
  • 的一种简单方法重置试用期大规模减轻您对用户的支持w蚂蚁给无论出于何种原因
  • 信任用户的二审判决是一个很好的卖点
  • 电力用户往往会转而反对软件太多的保护

我敢肯定有一些,但极少数,这些想法的例外。我会说:不要浪费你的时间在注册安全,但给

+1

我同意,不要浪费太多资源,使您的应用程序超级安全。黑客会找到一种方法来绕过它。 – 2010-08-30 14:30:07

+1

http://www.aquaticmac.com/是解决安全问题的好选择。 http://aquaticmac.com/cocoa.php在NSData上也有很好的扩展来做加密。如果你想覆盖99%的用户,我会推荐隐藏文件的方法,用一个明显的名字,例如“。” – Intentss 2010-09-01 18:54:33

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并将其设置为只读,但不应让应用程序询问用户密码。

3

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

查看Common Crypto摘要库。

这可以保护几乎所有的临时用户。虽然黑客有足够的动机可以找出一种避开的方法。

4

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

如上所述,在你的包中搞乱也是一个坏主意。这给你三个基本的选择。

1)不要担心太多。使用使用标准地点和方法的基本到期系统。您仍然可以在存储的数据中使用加密,但也知道这些也会被破坏。接受版权侵犯将发生,除非你的应用程序完全不受欢迎。

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

3)通过乱用应用程序包或者离开孤立文件成为“坏公民”。如果你这样做,至少要确保它们的名字明确,以便它们明显与你的应用程序相关。

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

您可以花制作的应用程序更好,或者给自己有关的人更好的感觉不使用它在试用期过后你的资源。其中之一可以增加您的销售额,而其中一个则不会。

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

3

艾伦Odgaard有一个关于如何使用OpenSSL生成可可软件/存储许可证密钥相当不错writeup。可能值得一读。

0

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

用法

导入头文件中的任何地方,你要使用的加密方法。

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

我建议产生的数字和字母的随机字符串:

#import <SecureNSUserDefaults/NSUserDefaults+SecureAdditions.h> 

然后,可能在你awakeFromNib方法设置加密密钥,。 然后,您必须将信息存储在您的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"]; 

我希望这有助于!