数据传输和密码加密的提案


A proposal for Data Transmission and Password Encryption

我需要实现一个免费的方案(无SSL证书),它可以满足敏感数据传输、保护和存储的要求,假设相互信任的第三方不可用,即我们不能使用SSL、TLS等。但这并不意味着我会自己实现SSL,我仍然想将加密和解密部分外包给现有的代码。

我起草了以下方案作为我的帐户和密码保护解决方案:

对攻击者的假设:

  1. 对协议有完整的了解。

  2. 可以访问大量常用密码词典。

  3. 可以窃听客户端和服务器之间的所有通信。

  4. 可以在客户端和服务器之间拦截、修改和伪造任意消息。

  5. 可以访问客户端上的源代码(包括加密代码)。

解决方案:

  • RSA(分别在客户端和服务器站点上加密和解密,公钥可以安全传输,如果密钥是由黑客获得的,则没有风险。)

  • SHA256/SHA512/Teece MD5(使用用户ID绑定Salt加密,两者都存储在服务器站点的数据库中。我在这里使用绑定Salt是为了避免常见密码和防止彩虹表。)

注册新用户:

  1. 首先在服务器端生成RSA密钥(存储在会话中);

  2. 向客户端发送公钥;

  3. 将公钥存储在javascript变量中;

  4. 在所有后续请求中,使用此密钥加密数据并发送到服务器;

  5. 使用会话中存储的私钥解密服务器端的用户帐户和密码;

  6. 用随机盐的单向加密算法对密码进行加密(就像常见的观点:SHA-256比MD5更强);

  7. 将用户id、哈希密码和随机盐(用户id绑定)存储到数据库中(避免使用通用密码和构建特定的彩虹表)。

现有用户登录:

  1. 首先在服务器端生成RSA密钥(存储在会话中);

  2. 向客户端发送公钥;

  3. 将公钥存储在javascript变量中;

  4. 在所有后续请求中,使用此密钥加密数据并发送到服务器;

  5. 使用会话中存储的私钥解密服务器端的用户帐户和密码;

  6. 使用用户帐户从数据库中获取哈希密码和salt;

  7. 使用获得的随机salt,采用单向加密算法对密码进行加密;

  8. 将加密后的密码与从数据库中获得的哈希密码进行比较;

  9. 确定登录成功或失败。

我是这方面的新手,我确实需要你的一些专业建议?这个方案足够安全吗?非常感谢。

这里的主要问题是,你正在做大量的工作,你没有得到比自签名SSL证书更好的安全性,你把自己设置为关闭任何可能的漏洞和维护系统安全的责任方(提示:这是一件大事)。

因此,如果你谈论的是一个普遍可用的web应用程序,你希望你的用户能够使用它,并对其安全性充满信心,那么为签名的SSL证书付费实际上是你唯一的选择。也就是说,一些人注意到:

  1. 你提到的哈希是可以的,但如果你想要真正的安全,可以使用pbkdf2之类的东西(谷歌一下,你就会发现真正安全的深度和难度)
  2. 如果不验证服务器的身份(登录已签名的SSL证书的目的),您将面临中间人攻击。如果其他人可以冒充你,并且完全有能力"在客户端和服务器之间拦截、修改和伪造任意消息",那么他们很容易从你的用户那里伪造任何信息。所以,如果你想让它成为一个完整的解决方案,这是一个你需要解决的问题

编辑:在阅读并思考了更多你想要的东西之后,我想我可能会为你找到一个解决方案。

实际上有两件事你可能想要保护:你的内容和你的用户凭据。你已经确定你的内容不值得每年花35美元来保护,这是足够公平和完全合理的。你仍然希望为你的用户凭据提供尽可能多的安全性,因为这些信息对他们和那些利用它的人来说都很有价值

即使你不想花钱来保护你的内容,你仍然希望只有有资格的用户才能访问它。因此,与其让用户创建一个值得保护的用户名/密码,不如让他们用自己的电子邮件地址登录。

有足够技能和动机的第三方可以访问你的内容和电子邮件地址,但从你所说的来看,你的内容可能不值得付出那么多努力,他们的电子邮件地址也没有那么敏感。但是,你仍然可以在世界和你的内容之间拥有一个登录网关,你可以利用双重选择加入来限制垃圾邮件等。你可以很容易地扩展这样的系统,包括用户名/密码,并在你的内容增长到需要时使用SSL。

如果攻击者"可以拦截、修改和伪造客户端和服务器之间的任意消息",他们可以更改客户端将获得的JavaScript代码。从这一点开始,您的整个机制就会崩溃,因为攻击者可以用自己的密码操作替换您想要执行的任何密码操作。

无论如何,JavaScript加密技术还不够好(请参阅本文)。

将SSL/TLS与自签名证书一起使用,至少可以让您有机会手动将该证书提供给客户端,或者让他们记住他们看到的第一个证书(与大多数人通过SSH连接时的做法类似:他们不一定第一次验证密钥,而是在后续连接中查找更改)。

使用公钥加密所有数据会在性能方面扼杀您。非对称密钥仅用于加密少量数据(例如对称会话密钥)。

您是否考虑过使用Kerberos这样的机制?它旨在通过非安全网络进行身份验证。这与你正在做的完全不同——看看,也许它会给你一些想法。