如何从 python 中的 osx 钥匙串中获取代理密码?

How to fetch proxy password from osx keychain in python?

目前我正在通过 运行 在 python

中使用以下 shell 命令获取密码

对于Http代理密码

security find-internet-password -s 192.168.1.38 -r htsx -P 808 -w

对于 Https 代理密码

security find-internet-password -s 192.168.1.38 -r htpx -P 808 -w

我通过运行以下代码

获得所有这些主机名和端口
>>> import urllib
>>> urllib.getproxies()
{'http': 'http://192.168.1.38:808', 'https': 'http://192.168.1.38:808'}

但是每次我 运行 来自 python 的上述 shell 命令时,我都被要求 Allow "security"访问钥匙串,如果我给 Always Allow 应用程序访问代理密码的钥匙串,那么代理密码甚至可以被我没有明确允许的其他应用程序访问。他们可以通过 运行ning 相同的命令访问代理密码(我已经在命令提示符下尝试过,这次它没有提示我并尝试从其他 python 脚本访问它也是没有征求我的许可)。

但其他应用程序如 AuthBroker 在访问代理时显示以下消息

我知道我正在授予应用程序 security 访问钥匙串的权限,但其他应用程序正在为自己请求权限。我的方法可能会危及系统的安全性。

我有两个问题:

  1. 访问代理密码钥匙串的推荐方法是什么?
  2. 有没有 python 库可以做到这一点?

在 OS X 上以任何语言执行此操作的推荐方法是使用 Keychain Services.

Keychain Services 主要提供 C API,它的文档仅适用于 C、ObjC 和 Swift。上面的编程指南 link 大部分与语言无关,但示例和函数引用的语法不会。

我相信 'SecKeychainFindInternetPassword` 是您想要的功能,但除非您先阅读背景,否则这对您没有任何好处。

据我所知,还没有人为此发布 Python 包装器。如果您熟悉 PyObjC,我依稀记得 PyObjC 邮件列表上的一个线程,其中有人包装了核心钥匙串服务功能,就像 Launch Services 开箱即用一样。或者,由于 API 是纯 C,而不是 ObjC,您可以通过 ctypes.

访问它

然而,最简单的解决方案可能是获得第三方 ObjC 包装器之一(我认为 SSKeychain.framework and Keychain.framework 是每个人都使用的两个,但不要引用我的话)。然后,您可以使用 PyObjC 中的 NSBundleNSClass API 动态加载它们。当然,这确实意味着您需要分发该第三方框架,因此请务必检查许可证。

如果你google for "Keychain Access Python", "SSKeychain Python", 等等,你会看到一些博文,但它们似乎都过时了几年(我的第一篇发现死了 link 到 SSKeychain...),所以我不确定他们会有多少帮助。

使用Python中的keyring库超级方便。安装对我来说很简单:

$ sudo easy_install keyring

然后,使用此处描述的简单 API:https://alexwlchan.net/2016/11/you-should-use-keyring/

$ python
>>> import keyring
>>> import getpass
>>> keyring.set_password('twitter', 'xkcd', getpass.getpass())
Password: 
>>> keyring.get_password('twitter', 'xkcd')
u'correct horse battery staple'

有关此密码背后的故事,请参阅 https://xkcd.com/936/。 :-)

我不确定这是否与您所指的代理密码完全集成,因为我只是用它来存储简单脚本的密码。