通过JAVA DataOutputStream发送密钥

时间:2015-02-14 20:48:12

标签: java datainputstream dataoutputstream secret-key javax.crypto

我正在使用对称密钥+ RSA开发FTP工具。我想通过dataoutputstream将我的密钥发送到服务器。我可以这样做吗?我试着跟着,

客户端:

 SecretKey secretKey = en_de_cryptor.returnSecretKey();
 String encodedKey = Base64.encode(secretKey.getEncoded());
 dout.writeUTF(secretKey.toString());  

服务器:

String secretKey = din.readUTF();
byte[] decodedKey = Base64.decode(secretKey);

但我无法获得解码密钥。我该如何解决这个问题,并在服务器端获取密钥。

2 个答案:

答案 0 :(得分:5)

正如大多数其他人所指出的那样,您遇到的问题是,您发送的非对称密钥中最重要的部分是明文,其中可以拦截密钥。当然你可以加密密钥,但这会引入其他加密问题来解决。如果使用对称加密算法来加密密钥,则需要解决密钥协议问题。双方如何以安全的方式就密钥达成一致,以便第三方不能拦截它?

在某种程度上,您正在重新解决SSL已经解决的问题。为什么不用它呢?此外,SSL已经过测试,安全专家已经过了25年。开发自己的版本意味着您可能陷入SSL开发人员已遇到的类似陷阱。

但是,如果必须重新实现,则需要更改算法。保护私钥的最安全方法是首先从不通过网络发送私钥。非对称加密允许您在客户端和服务器之间交换消息,而不存在对称算法具有的密钥协商问题。

这是一种解决密钥协议问题的算法:

  1. 让服务器生成非对称密钥。两种选择:
    1. 一次生成非对称密钥(即在服务器启动时),所有连接都使用相同的密钥。
    2. 为每个客户端连接时生成非对称密钥,使其更安全。
  2. 当客户端连接时,将服务器的公钥传输到客户端
  3. 客户端将为对称算法生成密钥(如何选择算法?SSL也解决了这个问题。)
  4. 客户加密密钥,使用服务器的公钥
  5. 客户端将加密的密钥传输到服务器。
  6. 服务器使用私钥解密消息以获取对称密钥。
  7. 现在,服务器和客户端可以使用对称加密交换任何加密邮件,第三方无法收听。
  8. 即使你这样做了,你仍然对中间人攻击持开放态度,第三方监听者可以欺骗客户端和服务器通过第三方发送未加密的数据,因为客户端会交换消息与客户端和服务器。只是一个简单的示例,说明如何自己实现这些内容可能会导致您创建一些不仅仅使用SSL的安全性。

    如果您确实发送加密的有效负载,您将要放弃DataInputStream并使用直接二进制流,这样您就不需要使用Base64Encoding将二进制有效负载转换为UTF字符串。

答案 1 :(得分:0)

  1. omg,不要那样做! base64没有给你任何安全保障。使用加密,而不是编码
  2. 发送secretKey.toString(未编码)而不是encodedKey