使用用户选择的密码进行公钥加密?
重点是设计一个简单的系统,用户可以在其中发送加密消息(在服务器的支持下)。
在这种情况下,客户端没有本地存储,因此我被迫使用用户可以在需要时选择、记住和输入的密码。 (我知道这会削弱整个系统,但这是一个硬性要求)
另一个要求是服务器不能存储明文私钥或任何其他可用于解密的数据消息(例如:只有用户可以读取加密消息,服务器管理员不应该能够)。
我的方法是在客户端生成非对称密钥对,在服务器上发布公钥以及私钥的加密副本(使用用户密码加密)。 然后,用户可以使用收件人发布的公钥向其他用户发送加密消息;当用户需要解密消息时,客户端从服务器获取他的(加密的)私钥,使用用户提供的密码进行解密,然后用于解密消息。
这有什么意义吗?这个系统设计有什么缺陷吗? (除了用户选择短密码或错误密码而产生的弱点之外) 这种方法是否已经在类似场景中使用过?
谢谢 :)
The whole point is designing a simple system where users are able to send encrypted messages between them (with support from a server).
In this scenario, clients have no local storage, so I'm forced to use passwords that users will be able to choose, remember and type when needed. (I know this weakens the whole system but this is a hard requirement)
Another requirement is that the server cannot store cleartext private keys or any other data which can be used to decrypt messages (eg: only the user can read encrypted messages, server admins should not be able to).
My approach would be to generate an asymmetric keypair on the client, publish public key on the server along with an encrypted copy of the private key (encrypted with the user password).
Users can then send encrypted messages to other users, using the recipient published public key; when a user needs to decrypt a message, his (encrypted) private key is fetched on the client from the server, decrypted with the password provided by the user and then used to decrypt messages.
Does this make any sense? Is there any flaw in this system design? (apart from the weakness derived from users choosing short or bad passwords)
Is this approach already used in similar scenarios?
Thank you :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果我理解正确的话,您想要创建一个系统,其中两个用户可以通过他们不信任的服务器发起私人通信。
这行不通。
在您设计的场景中,服务器可以生成自己的密钥对,并发布其公钥来代替用户的公钥。当用户加密消息并将其发送给其合作伙伴时,他们无法检测到服务器已替换其公钥。服务器解密消息,将其呈现给服务器管理员,并使用真实的合作伙伴公钥重新加密它(或他们制造的一些新消息),然后将其转发到目的地。
这里缺少的是证书颁发机构。这是一个受信任的第三方,对公钥和用户名之间的绑定进行数字签名。这种绑定称为证书。这样,当服务器向客户端提供用于加密的公钥时,客户端可以使用 CA 的公钥来验证证书,并确保他们要加密的公钥属于预期的接收者,而不是攻击者。
用户必须信任 CA,这可能比信任服务器管理员更容易接受。但是,还必须有一种防篡改的方式来存储 CA 证书。在实践中,这通常是使用基于密码的 MAC(消息验证码)来完成的。或者,CA 可以使用用户的私钥进行数字签名(从未见过这样做,但它会起作用)。但棘手的部分是从可信来源获取 CA 证书,绕过不可信的服务器。
至于用密码加密私钥,这种做法很常见,并且与您选择的密码一样安全。
或者,如果用户可以在带外相互共享秘密,则不需要公钥加密。客户端可以使用用户选择的密码对共享秘密进行加密,并将密文存储在服务器上。
If I understand correctly, you want to create a system where two users can initiate private communication through a server that they do not trust.
This won't work.
In the scenario you lay out, the server can generate its own key pair, and publish its public key in place of the users'. When a user encrypts a message, intending it for their partner, they can't detect that the server has substituted its public key. The server decrypts the message, presents it to the server admins, and re-encrypts it (or some new message that they fabricated) with the real partner public key, and forwards it to the destination.
What's missing here is a certificate authority. This is a trusted third party that digitally signs a binding between a public key and a user name. This binding is called a certificate. This way, when the server presents a public key to a client to use for encryption, the client can use the CA's public key to verify the certificate, and be assured that the public key they are about to encrypt with belongs to the intended recipient, and not an attacker.
The users have to trust the CA, which might be more palatable than trusting the server administrators. But, there must also be a tamper-proof way to store the CA certificate. In practice, this is often done using a password-based MAC (message authentication code). Or, the CA could be digitally signed with the user's private key (never seen this done, but it would work). But the tricky part would be getting the CA certificate from a trusted source, bypassing the untrustworthy server.
As far as encrypting the private key with the password, that is done very often, and is as safe as the password you choose.
Alternatively, if the users can share a secret with each other out-of-band, you don't need public key encryption. The client could encrypt the shared secret with a user-selected password, and store the cipher text on the server.
如上所述,该方案似乎是合理的,因为它应该允许某人向另一个人发送只有收件人可以阅读的消息。您可能已经想到了一些项目,但为了简洁而忽略了:
As described, the scheme seems reasonable in that it should allow someone to send another person a message that only the recipient can read. There are some items that come to mind that you may have already thought about but left out for brevity:
这听起来有点像 hushmail 所做的。然而,存在一个主要问题,因为他们拥有用户的私钥(加密的),所以他们只需要推送一个被黑客攻击的java小程序,该小程序会将用户的密码传输到服务器(他们确实这样做了)。
更好的解决方案是完全避免在服务器上保留该私钥。由于不需要本地存储,这就不再适用了。
为什么不通过预共享密码使用对称加密?无需客户端存储即可完成。我相信这就是 @erickson 在他的最后一段中所说的。
This sounds something like what hushmail did. However, there was a major problem in that, since they had the private key of the users (encrypted) they just had to push down a hacked java applet which would transmit the user's password to the server (which they did).
A much better solution is to avoid having that private key on the server at all. With the requirement of no local storage, that's out.
Why not use symmetric encryption via a pre-shared password? It can be done without storage on the client side. I believe this is what @erickson was saying in his last paragraph.
主要问题是,如果从服务器下载解密代码,则(服务器管理员或已到达服务器的黑客)可以替换该代码。客户端的用户应该信任服务器,但他无法验证服务器以信任它。
The major problem is that if the decryption code is downloaded from the server, one (either server admin or a hacker that has got to the server) can replace this code. The user on the client side should trust the server, but he has no way to verify the server in order to trust it.