0

正在为 Pastebin.com 编写一个 Mac OS X 仪表板小部件,它使用widget.setPreferenceForKey.

这样做是安全和好的做法吗?

4

2 回答 2

1

我知道这是一个老问题,但我现在正在尝试自己开发一个仪表板小部件,我遇到了同样的问题。我会分享我学到的东西。

首先,好消息是您不一定需要插件。您所需要的只是让您的小部件访问命令行。

OS X 实际上包含一个名为 的命令行实用程序security,它可以让您执行各种涉及钥匙串的事情。info security您可以通过输入终端来阅读它。我还没有达到可以从小部件本身中测试它的地步(仅在终端中),但从我收集到的信息来看,我认为这就是你所做的。任何人都知道更好,不要犹豫,做出改变。

将密码存储在钥匙串中

假设usernamepassword是我们已经设置的变量:

widget.system("/usr/bin/security add-generic-password -a \""+username+"\" -s \"My Awesome Widget\" -w \""+password+"\" -T \"/usr/bin/security\" -U);

命令分解

/usr/bin/security:该widget.system()方法需要我们正在执行的命令的完整路径。这个特定的命令位于 /usr/bin 中。

add-generic-password:security的许多命令之一。还有其他类型的密码项可以添加到钥匙串中,例如 Internet 密码,但我认为通用类型最适合这种情况。

-a:“帐户名”或用户名,与我们要存储的密码一起使用。钥匙串可能不是您存储用户名的主要位置,因为我们稍后需要它来查找密码,但是如果用户打开了我们的小部件的多个实例,每个实例都有不同的用户/密码组合,包括用户名到时候这里就让我们专门查一下那个密码。引号不是绝对必要的,但如果您的小部件的用户名允许有空格,您应该包括它们。

-s:我们正在创建的 Keychain 项的“服务名称”——换句话说,是冗长的、人类可读的名称。您的小部件名称可能在这里最合适。

-w: 密码。同样,如果您的密码可能包含空格,建议使用引号。

-T:允许毫无疑问地访问此钥匙串项目的任何应用程序的路径。如果没有此标志,以后任何尝试检索密码都会导致用户看到“安全人员想要使用存储在钥匙串中“My Awesome Widget”中的机密信息”提示之一,并且他们很可能不知道是什么这意味着它会吓坏他们。我在这里假设因为小部件用于security请求密码,security(而不是说,DashboardClient)是需要被授予访问权限的程序。

-U: 如果它已经存在,告诉security它更新这个 Keychain 项目,而不是仅仅失败。

从钥匙串取回密码

这在您获得密码后涉及一个额外的步骤,但它仍然应该不会太糟糕。

var messyPassword = widget.system("/usr/bin/security 2>&1 >/dev/null find-generic-password -ga \""+username+"\" -s \"My Awesome Widget\"").outputString;
scrubPassword(messyPassword);

命令分解

/usr/bin/security: 你好,警官。我们遇到了一些天气,嗯?

2>&1 >/dev/null: 的输出find-generic-password包括大量废话,否则我们在这种情况下不需要的可能有用的信息。幸运的是,它将密码与所有密码分开输出,因此可以使用这个额外的位自行捕获。(感谢 Macromates Ltd. 的 Allan Odgaard 的博客文章详细介绍了这个技巧。)

find-generic-password: 的对应物add-generic-password。后面的参数用作搜索条件。

-g: 告诉security实际上,你知道,输出密码。否则,我猜它只是......承认该项目存在的事实,然后退出?

-a:与我们要检索的密码一起使用的用户名。

-s:我们在编写add-generic-password命令时为小部件选择的人类可读的名称。

等等,什么scrubPassword()

好吧,问题是,即使从security' 的回复中删除了所有其他内容,您返回的字符串也不仅仅是密码。它更像是:

password: "nobodywilleverguessthis"

据我所知,我们必须使用正则表达式来破解该字符串并获得其中闪亮的密码珍珠。我不了解你,但正则表达式对我来说是噩梦,所以找到txt2re让我感到非常欣慰和兴奋,这是一个在线工具,可让您从要操作的字符串中对正则表达式进行逆向工程。你可以直接security将 's 的输出粘贴到 txt2re 中,然后抓取一段 JavaScript,从中提取密码。

注意: widget.system()还允许将处理函数用作第二个参数,因此您可以在此处调用您的scrubPassword()函数并跳过带有messyPassword变量的整个部分。正如我所说,security到目前为止,我只尝试从终端拨打电话,所以我没有任何实际使用widget.system().

从钥匙串中删除密码

当一个小部件的实例关闭时,我们可能不想让关联的密码弄乱用户的钥匙串,所以我们会做负责任的事情并捡起我们的垃圾。这个命令比其他两个命令简单一点,因为我们不需要创建任何东西或得到任何响应。

widget.system("/usr/bin/security delete-generic-password -a \""+username+"\" -s \"My Awesome Widget\"");

命令分解

/usr/bin/security: 通常。

delete-generic-password: 按照盒子上说的做,使用以下参数作为搜索(或者,更确切地说,搜索和销毁)标准。

-a:要取出的密码对应的用户名。

-s:小部件的人类可读名称。

希望这可以帮助!

于 2012-05-01T20:03:15.870 回答
0

不会。密码将不加密地存储在属性列表中。据我所知,没有直接的方法可以安全地存储来自小部件的信息。我唯一能想到的就是使用插件将密码存储在用户的钥匙串中。请参阅Widget Plugin InterfaceKeychain Services Reference

于 2011-03-02T22:57:28.127 回答