6

重点是设计一个简单的系统,用户可以在其中发送加密消息(在服务器的支持下)。

在这种情况下,客户端没有本地存储,所以我不得不使用用户可以在需要时选择、记住和键入的密码。(我知道这会削弱整个系统,但这是一个硬性要求)

另一个要求是服务器不能存储明文私钥或任何其他可用于解密消息的数据(例如:只有用户可以读取加密消息,服务器管理员不应该能够)

我的方法是在客户端生成一个非对称密钥对,在服务器上发布公钥以及私钥的加密副本(使用用户密码加密)。然后,用户可以使用收件人公开的公钥向其他用户发送加密消息;当用户需要解密消息时,他的(加密的)私钥在客户端从服务器获取,使用用户提供的密码解密,然后用于解密消息。

这有道理吗?这个系统设计有什么缺陷吗?(除了用户选择短密码或错误密码所带来的弱点)这种方法是否已经在类似的场景中使用过?

谢谢 :)

4

4 回答 4

2

如果我理解正确,您想创建一个系统,让两个用户可以通过他们不信任的服务器发起私人通信。

这行不通。

在您布置的场景中,服务器可以生成自己的密钥对,并代替用户发布其公钥。当用户加密消息并打算将其发送给他们的合作伙伴时,他们无法检测到服务器已经替换了它的公钥。服务器解密消息,将其呈现给服务器管理员,并使用真正的合作伙伴公钥重新加密它(或他们制造的一些新消息),并将其转发到目的地。

这里缺少的是证书颁发机构。这是一个受信任的第三方,它对公钥和用户名之间的绑定进行数字签名。这种绑定称为证书。这样,当服务器向客户端提供公钥用于加密时,客户端可以使用 CA 的公钥来验证证书,并确保他们将要使用的公钥属于预期的接收者,而不是攻击者。

用户必须信任 CA,这可能比信任服务器管理员更容易接受。但是,还必须有一种防篡改的方式来存储 CA 证书。在实践中,这通常使用基于密码的 MAC(消息验证码)来完成。或者,可以使用用户的私钥对 CA 进行数字签名(从未见过这样做过,但它会起作用)。但棘手的部分是从可信来源获取 CA 证书,绕过不可信的服务器。

至于用密码加密私钥,这种做法经常进行,并且与您选择的密码一样安全。

或者,如果用户可以在带外相互共享秘密,则不需要公钥加密。客户端可以使用用户选择的密码对共享密钥进行加密,并将密文存储在服务器上。

于 2010-12-18T00:05:56.387 回答
1

这听起来有点像 hushmail 所做的。然而,其中存在一个主要问题,因为他们拥有用户的私钥(加密),他们只需按下一个被黑客入侵的 Java 小程序,该小程序会将用户的密码传输到服务器(他们这样做了)。

一个更好的解决方案是完全避免在服务器上拥有该私钥。由于没有本地存储的要求,这已经过时了。

为什么不通过预共享密码使用对称加密?它可以在客户端没有存储的情况下完成。我相信这就是@erickson 在他的最后一段中所说的。

于 2010-12-18T07:36:43.083 回答
1

如上所述,该方案似乎是合理的,因为它应该允许某人向另一个人发送只有收件人才能阅读的消息。您可能已经想到了一些项目,但为简洁起见而忽略了:

  • 加密私钥时,请使用带有盐的 PBKDF2 之类的东西,以及一些相当大的迭代次数。
  • 这可能是暗示的,但不是用公钥加密,而是生成一个随机密钥(例如,如果使用例如 AES-256,则为 32 字节的随机数据)可能是有意义的。使用该密钥加密消息,使用公钥加密密钥,然后发送两部分。
  • 如上所述,没有发件人的标识。它允许发送纯粹的匿名消息。这可能是有意的,但如果不是,那么某种识别/认证将是必要的。
  • 与上一条有些相似,没有描述消息认证。攻击者可以更改加密的消息,而收件人无法知道它已被更改。虽然,如果是短信,很明显它已经被修改了,因为它只是乱码。但是,有些类型的数据可能不太容易判断它是否已被修改。
于 2010-12-17T23:19:14.857 回答
1

主要问题是,如果解密代码是从服务器下载的,那么一个人(服务器管理员或已经进入服务器的黑客)可以替换此代码。客户端的用户应该信任服务器,但他无法验证服务器以信任它。

于 2010-12-18T08:16:02.497 回答