我想用Java写一个洋葱路由器的非常简单的实现(但包括混合香菇)-许多公钥/私钥加密看起来非常简单,但是却很难理解最后一个路由器如何知道最终的洋葱皮已经'去皮'。
我当时在考虑对某种校验和进行编码,以便每个路由器尝试使用其私钥进行解密,并且如果校验和有效,则将新剥皮的洋葱转发给下一个路由器。
只有这样,(假设每次成功解密都会删除一部分校验和),才会有一种方法(查看校验和)来估计它与解密的接近程度-这是一个重大漏洞吗?校验和方法是否适当简化?
最佳答案
不管您提到什么问题,通常最好的做法是在加密/解密数据时包括一些完整性检查。但是,校验和并不真正适合于此。看看诸如SHA-256之类的安全哈希算法(标准Java密码框架中内置了一些实现)。
现在,回到您的原始问题...对洋葱的每个节点,您都将传递一个加密的“数据包”,但是该数据包将不仅包括要传递的实际数据,还将包括下一个节点的详细信息,您的哈希码以及其他任何信息,包括说明下一个“节点”是洋葱路由器还是实际最终主机的标志/指示。实际上,最后一个节点的数据将必须具有一些特殊信息,即与之通信的实际最终主机的详细信息。换句话说,最后一个节点知道洋葱已被剥皮,因为您将这一事实编码在最终接收到的数据中。
或者至少,我认为这就是我要做的... ;-)
N.B.我不认为加密本身并不那么复杂,但是可能需要注意一两个细节。例如,在普通的单一客户端-服务器对话中,您需要注意的一个细微之处是,永远不要使用相同的密钥对相同的数据块进行两次加密(或者至少可以归结为-研究“数据块模式”和“初始化向量”(如果您不熟悉此概念)。在一次客户端-服务器对话中,客户端和服务器可以指定初始化向量的各个部分。在洋葱路由器中,必须找到其他解决方案(我想,最坏的情况是,仅使用客户端单独生成的强烈生成的随机数)。