无法认证的情况?需要算法提示
情况是这样的:
服务器和客户端都可以信任(都运行在用户的电脑上)。受信任的用户在其计算机上和客户端上都有一个秘密密钥。该算法的目标是在不向服务器暴露密钥的情况下将可信用户验证为服务器上可信的。
技术困难:
我们使用的语言(Game Maker)既不快速也不精确。我们已经准备好了 MD5 散列的实现,但我和团队都没有能力/有时间来实现极其困难的加密算法。
This is the situation:
Server nor client can be trusted (both run on users' pc's). Trusted users have a secret key on their computer, along with the client. The goal of the algorithm is to authenticate trusted users as trusted on the server without exposing the secret key to the server.
Technical difficulties:
The language we use (Game Maker) isn't that fast nor precise. We have an implementation of MD5 hashing ready, but me nor the team is capable of/has the time for implementing incredibly hard crypto algorithms.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您也许可以仅使用 MD5 为每台服务器生成一个机密。我不确定这是否正确,所以不要相信我的话。
每个服务器都有一个唯一的 ID(可以是公共的),并且还有一个等于 MD5(受信任的秘密 + 唯一 ID)或类似的本地秘密。您必须通过某些外部安全通道将本地秘密获取到服务器上,但例如,如果它是通过 HTTPS 与服务器代码一起从单个公司站点下载的,并且如果您确保永远不会将本地秘密发送出去一个给定的唯一 ID 多次,那么我认为这是可以的。
然后,服务器可以将其 ID 连同服务器 ID 一起发送给客户端。受信任的客户端可以为自己生成
MD5(受信任的秘密+唯一ID)
,但不受信任的客户端无法生成它。这为服务器和受信任的客户端提供了一个共享密钥,可用于使用(例如)HMAC-MD5 进行身份验证。如果本地秘密泄露,那么它只会让不受信任的客户端能够愚弄该泄露的服务器,而不是其他服务器。
显然,这有弱点 - 例如,服务器和受信任客户端之间的 MITM 可以对服务器发出的任何挑战提供正确的响应,而无需知道任何秘密。但它不会将客户端的秘密暴露给服务器,也不会将服务器的秘密暴露给客户端,所以总比没有好。
它也有加密方面的弱点——MD5 有点被破坏。如果我是服务器并且我可以找到
x
使得MD5(x + my_id) == my_secret
,那么很可能x
就是秘密密钥。我不知道在给定一个或多个本地秘密的情况下找到 x 在计算上是否可行:这取决于 MD5 当前的损坏程度。我认为考虑到你的限制,MITM 绝对是不可避免的,尽管我可能是错的。受信任的客户端无法区分一台服务器和另一台服务器,特别是服务器是否正在使用其正确的唯一 ID,因此始终会对 MITM 传递的任何质询给出正确的响应。但是,如果消息包含攻击者无法控制的某些值,例如服务器生成的随机数或日期,那么简单的窃听不会导致重放攻击。我不知道在不使用非对称加密和 PKI 的情况下防止 MITM 的方法,也就是说,您没有时间/能力用您的语言实现不同的基本加密构建块。
可以使系统提供某种类型的密钥撤销。如果您将公司权限设置为按需分发成对的
(随机服务器 ID,本地秘密)
,那么服务器可以不时更新其本地秘密(并同时更改其 ID) )。然后,您可以更改受信任的秘密,服务器将停止对使用旧秘密的客户端进行身份验证,并在下次获得 ID 时立即开始对使用新秘密的客户端进行身份验证。如前所述,这是一个相当痛苦的移交,如果您正在构建这样的计划,您可能希望稍微软化它。You might be able to produce one secret per server using only MD5. I'm not sure this is correct, so don't take my word for it.
Each server has a unique ID, which can be public, and also a local secret equal to
MD5(trusted secret + unique ID)
or similar. You'll have to get the local secret onto the server by some external secure channel, but for example if it's downloaded from a single company site by HTTPS along with the server code, and if you ensure that you never send out the local secret for a given unique ID more than once, then I think that's OK.The server can then send its ID to the client along with the server ID. A trusted client can generate
MD5(trusted secret + unique ID)
for itself, but an untrusted client can't generate it. That gives the server and the trusted client a shared secret, which can be used to authenticate using (for example) HMAC-MD5.If a local secret leaks, then it only gives untrusted clients the ability to fool that leaky server, not other servers.
Obviously this has weaknesses - for example a MITM between a server and a trusted client can provide the correct response to any challenge the server makes, without knowing any secrets. But it doesn't expose the client's secret to the server, and it doesn't expose the server's secret to the client, so it's somewhat better than nothing.
It also has cryptographic weaknesses - MD5 is somewhat broken. If I'm a server and I can find
x
such thatMD5(x + my_id) == my_secret
, then chances arex
is the secret key. I don't know how computationally feasible it is to findx
given one or more local secrets: that depends on the current degree of broken-ness of MD5.I think MITM is absolutely inevitable given your constraints, although I may be wrong. A trusted client has no way to tell one server from another, in particular whether a server is using its proper unique ID, and therefore will always give the correct responses to any challenges that a MITM passes along. However, provided that the messages include some value that the attacker cannot control, such as a server-generated nonce or the date, then simple eavesdropping doesn't lead to replay attacks. I'm not aware of a way to prevent MITM without using asymmetric encryption and a PKI, that is to say different basic crypto building blocks that you don't have the time/capacity to implement in your language.
It's possible to make the system provide for key revocation of a sort. If you set up your company authority to hand out pairs of
(random server ID, local secret)
on demand, then servers could update their local secret from time to time (and change their ID at the same time). Then you could change the trusted secret, and servers would stop authenticating clients that use the old one, and start authenticating clients that use the new one, as soon as they next get an ID. As stated that's a fairly painful handover, you'd probably want to soften it a bit if you were building in such a scheme.扩展哈罗德的评论,适合此问题的零知识证明方案是 Feige-Fiat-Shamir。佩吉向维克多证明她知道大模数的因式分解,但没有透露给维克多。
该方案不支持撤销,如果您不能相信您的“可信”用户不会泄露秘密,那么这将是一个严重的问题。
Expanding on harold's comment, a zero-knowledge proof scheme appropriate for this problem is Feige-Fiat-Shamir. Peggy proves to Victor that she knows the factorization of a large modulus without revealing it to Victor.
This scheme doesn't support revocation, which is a serious problem if you can't trust your "trusted" users not to reveal the secret.
您不应该设计自己的加密系统。找到一个现有的加密系统并将其移植。 (即使这样也会让你遭受诸如定时攻击之类的事情......)
请允许我演示一下犯错误是多么容易。这是一个基本的身份验证方案:
看起来很安全,对吗?没有。
You should not design your own crypto system. Find an existing one and port it. (Even that can expose you to things like timing attacks...)
Allow me to demonstrate how easy it is to make a mistake. Here's a basic authentication scheme:
Seems secure, right? Nope.
好吧,如果您不需要超级安全的系统,那么服务器或用户应该“问”:
我可信吗?
不过,您需要如何信任用户。简单的方法是,当用户添加他的密钥或生成它时,它会向服务器发送一些信号:好的,我已经验证,请记住我受信任,在这里,用于检查的特殊密码: *苹果*。我应该回答*Pear*。
然后当用户连接到服务器时,服务器询问:Apple?
,客户端回答:Pear!
。服务器授权客户端。双向工作。不过,如果您想要一些更好的解决方案,您将需要一些中央服务器,女巫会给出:Well, if you dont need super secure system then server or user should "ask":
Am I trusted?
Still, some how you need to trust the user. Simple way is, when users adds the his key, or it beaing generated, it send some signal to server that:OK, I have validated, please remember that im trusted and here you go, the special passprase to check that: *Apple*. I should answer *Pear*.
And then when user connects to server, server ask:Apple?
, and client answers:Pear!
. Server authorizes client. Works both ways. Still, if you want some MUCH better solution, you will need some central server, witch will give: