基于 TCP 的 Java 可序列化安全性

Posted

技术标签:

【中文标题】基于 TCP 的 Java 可序列化安全性【英文标题】:Java serializable security over TCP 【发布时间】:2014-04-12 12:37:19 【问题描述】:

我有一个 TCP/IP 聊天应用程序,它来回发送 ChatMessage 对象,这些对象包含消息的 int 类型和 String 消息。

我的问题是:我怎样才能使它更安全?

谢谢!

【问题讨论】:

加密消息,你需要阅读加密等等 根据安全威胁来定义安全。 或者你可以使用CipherOutputStream 我建议不要对这个任务使用 Java 序列化。它打开了一整罐蠕虫。 (当然还要使用 https。) 【参考方案1】:

我可以想到两种方法:CipherOutputStreamSSLSocket

密码输出流

byte[] keyBytes = "1234123412341234".getBytes();
final byte[] ivBytes = new byte[]  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 
     0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f ; //example

final SecretKey key = new SecretKeySpec(keyBytes, "AES");
final IvParameterSpec IV = new IvParameterSpec(ivBytes);
final Cipher cipher = Cipher.getInstance("AES/CFB8/NoPadding"); 
cipher.init(Cipher.ENCRYPT_MODE, key, IV);

//assuming your Socket is called "socket"
CipherOutputStream cstream = new CipherOutputStream(socket.getOutputStream(), cipher);
... 
//code to write ChatMessage object

或者,您可以使用 SSL:how to do ssl socket programming

【讨论】:

显然比提供的更安全的密钥和 IV :) 在源代码中嵌入密钥可能不是最好的主意。最近损失了价值 50 亿美元的比特币有助于证明这一点。 @TomHawtin-tackline 是真的。该代码只是一个简单的示例来演示用法。 OP 不应逐字使用此键,因为键根本不是一个好键... 但是示例会被复制。 (甚至是确切说明不该做什么的例子。)密钥管理是问题中最困难的部分。【参考方案2】:

假设您需要一个提供数据ConfidentialityIntegrityUser Authenticity 的安全系统,以下是您使用伪代码执行此操作的方法。 (http://en.wikipedia.org/wiki/Information_security)。无论如何,这些都是安全聊天系统的一般要求。

    使用Public Key Crypto 为每个人提供一个公钥/私钥对 当 2 个用户第一次开始聊天时,用户 A 会生成一个Symmetric KeySK 用于加密他和用户 B 之间的消息。 用户A用B的公钥加密SK并发送给B B 解密 SK,现在他们使用 SK 加密他们之间的进一步消息。

现在您可以开始学习这些概念,并且它们的实现相当简单。对于算法,最常用的是:

    RSA 用于公钥加密 AES 用于对称密钥加密

这两种算法都有可用的 Java 实现,请查看 Bouncy Castle 加密 API 包。

注意:如果您使用的是网络应用程序,并且只需要安全地传输消息,您可以按照 cmets 中的建议使用SSL。

【讨论】:

以上是关于基于 TCP 的 Java 可序列化安全性的主要内容,如果未能解决你的问题,请参考以下文章

10-java安全——java反序列化CC3和CC4链分析

10-java安全——java反序列化CC3和CC4链分析

Tcp三次握手与四次挥手透析

Tcp三次握手与四次挥手透析

Tcp三次握手与四次挥手透析

Tcp三次握手与四次挥手透析