使用用户选择的密码进行公钥加密?

时间:2010-12-17 22:46:02

标签: security password-protection public-key public-key-encryption

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

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

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

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

这有什么意义吗?这个系统设计有什么缺陷吗? (除了用户选择短密码或坏密码导致的弱点) 这种方法是否已经在类似场景中使用过?

谢谢:)

4 个答案:

答案 0 :(得分:2)

如果我理解正确,您希望创建一个系统,其中两个用户可以通过他们不信任的服务器启动私人通信。

这不起作用。

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

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

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

对于使用密码加密私钥,这种做法很常见,并且与您选择的密码一样安全。

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

答案 1 :(得分:1)

如上所述,该方案似乎是合理的,因为它应该允许某人向另一个人发送只有收件人可以阅读的消息。您可能已经考虑过一些项目,但为了简洁而遗漏了这些项目:

  • 加密私钥时,请使用类似PBKDF2的盐和一些相当大的迭代次数。
  • 这可能是隐含的,但是不是用公钥加密,而是生成随机密钥(例如,如果使用例如AES-256,则为32字节的随机数据)可能是有意义的。使用该密钥加密消息,使用公钥加密密钥,然后发送两个密钥。
  • 如上所述,没有发件人的身份证明。它允许发送纯匿名消息。这可能是有意的,但如果没有,那么就需要进行某种识别/认证。
  • 与前一个条目有些类似,没有描述消息验证。攻击者可以更改加密的邮件,收件人将无法判断它是否已更改。虽然,如果它是一条短信,很明显它已被修改,因为它只是乱码文本。但是,有些类型的数据可能不容易判断它是否已被修改。

答案 2 :(得分:1)

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

更好的解决方案是避免在服务器上拥有该私钥。由于没有本地存储的要求,就是这样。

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

答案 3 :(得分:1)

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