自定义系统中的基于HTTP的认证/加密协议

1 投票
3 回答
1135 浏览
提问于 2025-04-16 01:00

我们有一个自定义程序,需要在客户端和服务器之间进行认证和加密的通信(这两个都是用Python写的)。

我们正在从自定义的Diffie-Hellman+AES方案转向一种非传统的RSA+AES方案。所以我很想听听大家对我这个想法的看法。

前提条件:客户端有一个128位的注册密钥,这个密钥在认证过程中必须保密——这个密钥也是服务器和客户端之间唯一共享的秘密。

  1. 客户端通过不安全的通道联系服务器,请求服务器的RSA公钥。
  2. 然后客户端向服务器发送请求:
    [接下来是伪代码]


       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。

Apache Mod_Proxy

NginX作为反向代理

4

别再重复造轮子了,直接用HTTPS吧。

服务器可以给客户端发放证书,并把这些证书存储在数据库里。客户端可以拿到服务器自己签发的证书来进行验证。服务器可以通过使用Apache的HTTPS环境变量来验证客户端。

撰写回答