我目前正在开发一个插件,很可能我会在公共插件存储库中发布它,以便其他人可以使用它。

该插件将使用API​​并使用此API您需要传递用户名和密码。因此,我的插件需要将这些登录凭据存储在数据库中。尽管API需要使用纯文本格式,但我不想将它们存储为纯文本格式。

所以我的问题是如何存储这些敏感信息?散列已经存在,因此必须进行某种加密。

在WordPress中,有一个可以使用的唯一密钥,该密钥会因博客而异?我应该使用哪些PHP函数进行加密和解密?我正在寻找在所有WP安装中都更有可能起作用的功能。

评论

这有点无法解决。是否需要可逆加密的数量无关紧要。如果WP可以解密它并且WP被破坏,那么加密就没关系。

但是,为什么您的API需要知道密码? API知道用户知道密码还不够吗?

@One Trick Pony-需要存储密码,以便无需用户干预即可自动执行该过程。

@Rarst-我知道如果WP被破坏了,那么密码也会被破坏。我不能阻止这一点。我可以防止的是,如果获得了SQL转储,则密码不是纯文本的。

@Brady是的,如果仅破坏了SQL转储,则加密将有所帮助。但是我发现这种情况不太可能。如果您具有数据库访问权限,那么也很容易破坏WP。

#1 楼

尽管我同意前面的答案,但要回答您实际提出的问题,想到的是对wp-config.php使用以下常量之一:

define('AUTH_KEY',        'redacted');
define('SECURE_AUTH_KEY', 'redacted');
define('LOGGED_IN_KEY',   'redacted');
define('NONCE_KEY',       'redacted');


它们在wordpress的安装中是唯一的-是有关wordpress中现有键的唯一选择。备用方法是添加您自己的相似常量,该常量是通过将其中一个相对于管理员电子邮件地址或相似的哈希值进行哈希处理而构建的-然后将其存储在隐藏的设置选项中-以防止有人在您输入后意外修改密钥而丢失密钥插件已安装。危险是,如果它们在初始安装时不是唯一的,但是管理员/站点所有者决定在事后纠正错误,那么他们就不应无意间破坏了您的密码加密。

加密/解密功能-快速的Google搜索会返回以下列表,并显示符合要求的代码:http://maxvergelli.wordpress.com/2010/02/17/easy-to-use-and-strong-encryption -decryption-php-functions /

function encrypt($input_string, $key){
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $h_key = hash('sha256', $key, TRUE);
    return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $h_key, $input_string, MCRYPT_MODE_ECB, $iv));
}

function decrypt($encrypted_input_string, $key){
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $h_key = hash('sha256', $key, TRUE);
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $h_key, base64_decode($encrypted_input_string), MCRYPT_MODE_ECB, $iv));
}


此处是此处使用的AES加密的一些文档:http://www.chilkatsoft.com/p/php_aes.asp

#2 楼

这正是OAuth所针对的情况。

从OAuth主页:


对于服务提供商开发人员...

如果您要支持...


Web应用程序
服务器端API
mashups

如果要存储受保护的数据代表您的用户,他们不应在网络上散布密码以获取访问权限。使用OAuth可以使您的用户访问其数据,同时保护其帐户凭据。


OAuth的优点是您不需要存储用户密码。初次安装插件时,系统会要求他们使用用户名和密码通过应用程序登录(通常,该页面与API托管在同一服务器上,并加载到页面重定向,thickbox或iframe中) 。

用户登录后,服务器(您的系统)会创建一个安全密钥,其系统(WordPress)可以使用该密钥与API进行接口。该密钥对于用户帐户和网站是唯一的-并赋予应用程序(在WordPress上)代表用户使用API​​进行操作的权限,而无需每次都传递其身份验证信息。

如果要查看运行中的示例,请查看Jetpack。

当您激活插件时,它会抱怨其未连接。当您“连接”它时,您可以通过WordPress.com输入您的凭据,并设置WordPress及其API之间的OAuth交互。

您只需执行一次,并且您的WordPress.com用户名/密码永远不会存储在本地WordPress数据库中。

评论


使用它会很好,但是我要处理的API不是我的,并且他们没有OAuth系统。

–斯科特
2011年8月5日在13:48

在那种情况下,您唯一的真实选择就是接受您需要将密码存储在数据库中,并且是否对密码进行加密实际上对安全性没有实质性影响。正如上面其他提到的那样,如果它在数据库中并且加密是可逆的,那么任何可以访问WordPress(合法或被黑)的人都可以想象得到它。

–EAMann
2011年8月5日在16:35

#3 楼

这是一个重要的问题,因为许多服务仍然不支持OAuth,并且在选项数据库中存储密码使密码对每个Wordpress插件都可读(请参见上面的评论)。

(目前还不是)一个真正的问题答案,而且评论太久。我希望对此进行讨论,以期提出解决此“无法解决”问题的“最佳”解决方案。

让我认为可以加密密码的基本思想是以下内容:

每个用户都有一个秘密信息:他们的Wordpress密码。应该有可能将凭据存储到使用秘密的密码形式派生的第三方服务中,并且仅在用户登录时才对凭据进行解密。

这样就应该至少可以做到无法从Wordpress文件和数据库的副本中窃取密码。它无法解决其他插件窃取凭据的问题,因为每个插件都可以在登录期间捕获纯文本密码。

解密实际上很容易:假设我们已经在数据库中存储了第三方服务的加密版本,我们可以连接到'authenticate'过滤器或覆盖wp_authenticate()函数,生成一个纯文本用户密码的盐化哈希(通过wp_hash_password()),将该哈希密码作为加密密钥存储在私有位置,直到用户注销(使用'wp_logout'钩删除密钥),并在每次需要第三个密码时使用它-方密码来解密数据库中的加密值。

虽然我认为应该可以进行此工作,但是仍然存在一些未解决的问题:


怎么做加密?可能会存储纯文本密码,直到用户注销并再次登录,然后在'authenticate'期间进行加密。可能会提示用户登录以保留该时间段,直到发生这种情况为止。
在哪里存储密钥以及如何在注销期间将其删除?我是否正确理解'authenticate'仅在用户实际登录时才运行?
如果现在有存储哈希密码的方法,也许可以改为从会话cookie派生密钥?
处理密码更改?看起来可以捕获这样的密码更改,然后必须使用从新密码派生的密钥对第三方密码进行重新加密。
是否可以提供多用户支持?理想情况下,希望管理员用户能够在设置中设置第三方密码,然后特权较低的用户可以使用该密码与第三方服务进行交互,理想情况下,即使不向其透露这些密码。为此,管理员用户将需要能够为其他用户只能自己生成的所有用户生成密钥。有可能吗?


评论


与此相关的另一个问题:尽管您可以捕获密码更改,但是如果用户完全丢失了密码,然后进行了密码重置,则将无法访问旧密码以使用新密码进行解密和重新加密。

– tobek
20-2-26在5:44

真正。这同样适用于任何其他密码管理器类型的软件。

– cgogolin
20 Mar 2 '20 at 21:52