繁体   English   中英

存储密码以登录第三方API

[英]Storing passwords to login to 3rd party APIs

我正在使用Node&Express为后端编写交易应用程序。 每个用户都有自己的应用程序登录名,但是为了使其有用,应用程序还需要登录到该用户的经纪帐户。

有问题的经纪人帐户具有REST API,您可以在其中发布该系统的登录名和密码。 该API不提供SSO或OAuth作为身份验证的选项。 进行身份验证的唯一方法是发布uid和密码。

因此,这里涉及两种登录:一种是我的应用程序登录,另一种是完全独立的经纪帐户登录。 这些登录中的每一个都使用不同的用户ID和密码。

我遇到的问题是弄清楚如何存储经纪帐户的密码。 我知道完全存储密码是个坏主意。 但是,如果我存储的只是经纪人密码的盐渍哈希,我将无法撤消该密码并找回实际密码。 因此,除非用户再次输入该密码,否则我的应用程序将无法登录到经纪帐户。

(顺便说一句,还有另一个程序可以做到这一点。https://dough.com要求用户登录面团,然后还必须登录TD Ameritrade。两次登录是我希望的避免。)

是否存在合理且安全的方法来存储此第三方API的密码,以便我的应用可以代表用户登录而无需强迫用户每次使用我的应用时都提交密码? 我了解这里存在很大的安全风险。 如果答案是否定的,那么我不会。

编辑与强制-真正的解决方案是不这样做。 尽管在技术上可行,但几乎可以肯定它不会正确实施,并且会公开用户的密码。

是的,确实有,但是这并不是一件容易的事,实现是关键。 您需要的是JavaScript OpenPGPJS库

为了建立一个较为安全的系统,不允许您的后端解密密码。 这是JS库进入的地方,该库通过浏览器提供PGP加密。

您可以将PGP密码作为用户密码的基础,或者使它们提供新的密码进行解密。 或者,您可以生成用于密码加密的随机密钥,然后创建可以访问随机密钥的主密钥-使用用户输入对主密钥进行加密。

无论采用哪种方法,都需要让他们输入密码以便在需要时解密记录,或者将他们的密码添加到他们的本地会话中。 前者是安全的,而后者则具有明显的安全隐患。

如示例所提供的,使用密码对简单字符串进行加密:

var options, encrypted;

options = {
    data: 'Hello, World!',      // input as String
    passwords: ['secret stuff'] // multiple passwords possible
};

openpgp.encrypt(options).then(function(ciphertext) {
    encrypted = ciphertext.data; // '-----BEGIN PGP MESSAGE ... END PGP MESSAGE-----'
});

解密:

options = {
    message: openpgp.message.readArmored(encrypted), // parse armored message
    password: 'secret stuff'                         // decrypt with password
};

openpgp.decrypt(options).then(function(plaintext) {
    return plaintext.data; // 'Hello, World!'
});

我认为您有一些选择,而您选择的决定应取决于您要承担的风险。 如果您如所暗示的那样是财务数据,我认为该决定显然应该不做任何事情。

一种选择是使用从用户本地密码派生的密钥将加密的第三方API密码存储在服务器上。 由于您不存储用户的本地密码,因此只有在拥有用户本地密码时,才可以在用户登录时解密第三方API密码,并且如果您以后希望通过该调用来假冒该用户的API,就可以从那里解密将第三方密码的纯文本版本保留在服务器内存(用户会话)中。 我认为,尽管在某些应用程序中这可能是一个可行的选择,但对于财务数据而言,这是不可接受的。

您可以做的另一件事是像Dave Lasley在他的回答中描述的那样用Javascript加密第三方API密码。 尽管这可行,但会增加很多复杂性,正如他还指出的那样,实现将是关键。 如果不引入漏洞,很难做到这一点并随着时间的推移进行维护。 同样,Javascript加密也有其问题,最佳实践是不要在Javascript中进行加密。 您必须将第3方API密码保留在Javascript内存中,这是一个非常弱的控件,任何单个XSS都可以从那里窃取它(任何其他浏览器存储都比内存中的Javascript对象更糟)。 同样,第三方API也需要支持您域中的CORS(或者显然是*)。

我认为,执行此操作的唯一好方法是使用OAuth2进行仔细的实现。 如果API不支持该功能,那么很遗憾,您不应该这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM