自定义系统中的基于HTTP的认证/加密协议
我们有一个自定义程序,需要在客户端和服务器之间进行认证和加密的通信(这两个都是用Python写的)。
我们正在从自定义的Diffie-Hellman+AES方案转向一种非传统的RSA+AES方案。所以我很想听听大家对我这个想法的看法。
前提条件:客户端有一个128位的注册密钥,这个密钥在认证过程中必须保密——这个密钥也是服务器和客户端之间唯一共享的秘密。
- 客户端通过不安全的通道联系服务器,请求服务器的RSA公钥。
- 然后客户端向服务器发送请求:
[接下来是伪代码]
RegistrationKey = "1dbe665ac7a944beb67f106f779e890b"
clientname = "foobar"
randomkey = random(bits=128)
rsa_cp = RSA(key=pubkey, data=randomkey+clientname)
aes_cp = AES(key=RegistrationKey, data=RegistrationKey+rsa_cp)
send(aes_cp)
3. 服务器随后回应:[接下来是伪代码]
# Server decrypts the data and sees if it has a valid RegistrationKey, if it does...
clientuuid = random(bits=128)
sharedkey = random(bits=128)
rsa_cp = RSA(key=privkey, data=clientuuid+sharedkey)
aes_cp = AES(key=randomkey[got from client], data= rsa_cp)
send(aes_cp)
现在双方都知道了“clientuuid”和“sharedkey”,客户端可以稍后用这个来进行认证。上面的方法应该是安全的,即使攻击者后来得知了注册密钥,因为他必须破解RSA密钥,并且中间人攻击(针对RSA)应该会阻止认证正确完成。
我看到的唯一可能的攻击方式是,攻击者知道注册密钥并且能够在认证过程中篡改流量。我说得对吗?
我真的很想听听你们对这个方法有什么要添加或删除的意见,如果你知道更好的方式来进行这种交换,也请告诉我。
附注!我们目前使用的是Diffie-Hellman(我自己写的库,可能有缺陷),我们也尝试过TLSv1.2和预共享密钥(因为某种原因没有成功),而且我们被限制在http协议上,因为我们需要在django中实现这个功能。由于我们使用http,我们尽量减少请求和响应的次数(没有会话是最好的)——一次请求是最理想的 :)
如果你对具体细节有任何问题,请问我。
所以,亲爱的加密/安全专家们,请给我一些帮助吧 :)
3 个回答
1
- 我觉得注册密钥并没有增加什么真正的安全性。
- 它需要更多的随机数(用来防止重放攻击)。
- 它需要更多的填充(否则消息太小,容易被破解)。
- 一个算法可以被证明是安全的,你可能想要这样做。
- 大多数加密问题出在实现上,而不是算法本身(比如时间攻击)。
3
不,使用SSL。自己重新发明加密系统是个坏主意。
你可以做的很简单,就是设置一个反向代理。把你的Django应用运行在一个较高的端口上(比如8080),并让它只接受来自本地地址(127.0.0.1)的连接。然后在443端口(标准的HTTPS端口)上运行反向代理,把所有请求转发到Django应用上。但要用你网站的证书来设置反向代理,并让它成为一个SSL端点。这样,转发到Django应用的请求就只是普通的HTTP,而不是HTTPS。
4
别再重复造轮子了,直接用HTTPS吧。
服务器可以给客户端发放证书,并把这些证书存储在数据库里。客户端可以拿到服务器自己签发的证书来进行验证。服务器可以通过使用Apache的HTTPS环境变量来验证客户端。