我需要加密将发送/接收的数据,客户端<>服务器,反之亦然。
由于我现在不能使用SSLStream,我正在寻找其他替代方案。
在考虑我的替代方案时,我纠结于如何以无法读取/拦截的方式将数据发送到客户端。
以下是我的想法:
-
客户端/服务器将在应用程序中有一个RSA私钥,该私钥将从字符串中加载,以加密/解密从服务器接收的数据。
-
在初始连接请求之后,服务器将发送会话id以及内部AES密钥/iv。
-
从这里开始,客户端将同时使用RSA和AES进行通信。
我想听听有经验的人的一些新想法或更好的方法来做我需要的事情,这就是:
将加密数据从客户端发送到服务器,反之亦然,而无需使用SSLStream,并且具有良好的安全级别。
我知道在客户身上拥有私钥是有风险的,但我还没有找到更好的解决方案。
如果你真的不能使用SSL,你可以自己构建穷人的SSL:
客户端知道RSA公钥,服务器知道相应的私钥。
为了进行通信,客户端创建一个可以与AES一起使用的随机会话密钥。它使用RSA公钥对其进行加密,并将其发送到服务器。它使用AES会话密钥对其余通信进行加密。
服务器使用RSA私钥对第一条消息进行解密,从而获得会话密钥。它在剩下的通信中使用这个密钥。
这样客户端就不包含任何秘密,但通信本身是私有的。这个方案主要缺少的是客户端身份验证。
您还应该为服务器->客户端和客户端->服务器流使用不同的nonce/IV。您可能还想添加完整性检查(MAC)。
实现这一点的唯一方法是使用共享机密:客户端和服务器都知道,但其他人都不知道。
公钥SSL的工作前提是证书(以及密钥对)被锁定到特定的服务器/域,该服务器/域可以通过第三方(签名机构)独立确认。
一旦你摆脱了这个前提,你就很容易受到公钥加密的中间人攻击,因为你无法保证你在和谁说话(或者至少你无法保证有人不会拦截/转发你的信息)。
如果你使用共享秘密,你不需要公钥、证书或其他任何东西,但如果任何未经授权的一方发现了你的秘密,你就完蛋了。
一种可能的方法:
-服务器有一个众所周知的公钥和一个没人知道的私钥(甚至连客户端都不知道)
-客户端生成一个"握手"数据包,并使用服务器的公钥对其进行加密。握手数据包包含您需要的任何初始化/身份验证内容,以及用于AES加密的随机生成的密码短语+IV。
-服务器使用其私钥解密握手数据包,现在可以访问AES密码短语+IV。它以"ACK"数据包作为响应,指示其已就绪。
-现在,客户端可以使用AES密码对称加密发送数据,服务器可以解密,反之亦然。
客户端不需要捆绑任何私钥。RSA是专门为数据交换而设计的,不需要共享密钥。