过去几天我一直在玩Bouncy Castle(java),我已经达到了这样的程度,我相信我可以通过Diffie-Hellman交换安全地交换密钥。
阅读了很多帖子,强调了正确实施加密交换的难度,我希望你对我的工作表示诚实的意见。 所有潜在的密码操作都基于Bouncy Castle,因此可能被认为是可靠的。
String message = "Hello World";
AESCipher aes_client = new AESCipher(256);
RSACipher rsa_server = new RSACipher(2048);
// (Public key sent over the wire)
RSACipher rsa_client = new RSACipher(rsa_server.getPublicKey().getModulus(),
rsa_server.getPublicKey().getExponent());
// The client encodes his AES key with the RSA public key:
byte[] aes_key = rsa_client.encode(aes_client.getKeyBytes());
byte[] aes_iv = rsa_client.encode(aes_client.getInitializationVector());
// (Data sent back over the wire)
byte[] decoded_aes_key = rsa_server.decode(aes_key);
byte[] decoded_aes_iv = rsa_server.decode(aes_iv);
// The server creates an AES server which uses the client key:
AESCipher aes_server = new AESCipher(decoded_aes_key, decoded_aes_iv);
byte[] encoded_message = aes_client.encode(message.getBytes());
byte[] decoded_message = aes_server.decode(encoded_message);
System.out.println(new String(decoded_message));
这次交换可以被认为是安全的吗?我是不是应该坚持使用SSL套接字,尽管我的努力工作会让我受伤? 提前感谢您的意见!
(顺便说一下,我的Bouncy-Castle-Wrapping-Library是完全开源的,所以如果你想要存储库的URL,请告诉我。)
答案 0 :(得分:2)
(您的协议中没有Diffie-Hellman,只有RSA和对称加密。)
第一个基本注释是您的协议容易受到主动攻击。 “中间人”是一个经典(攻击者截获公钥,用他自己的公钥代替)。此外,您只有对称加密,但没有MAC。让我们假设您的攻击模型仅与被动攻击者有关;大多数时候,这至少可以说是一个非常大胆的假设。实际上,我很难想象这会适用的情况:一个窃听者,他可以查看传输的字节,但无法发送自己的消息。除非你使用完整性检查在经过身份验证的隧道中运行整个事情(SSL有一种模式,但这种方式失败了。)
您正在加密IV,这是不需要的(IV不是密钥,否则它将被称为“密钥”,而不是IV)。您需要为每个加密消息随机生成IV。假设您使用CBC模式,可以接受来自消息的最后一个加密块用作下一条消息的IV。然而,将IV用于具有相同对称加密密钥的两个不同消息将是致命的。由于Bouncy Castle没有任何名为AESCipher
的类,因此您的示例代码不会告诉我们您是否使用具有正确链接模式的AES并正确进行IV管理。另请注意,只要按顺序发送消息,重复使用上一条消息中的最后一个加密块,就不会丢失任何消息。更强大的解决方案是:
java.security.SecureRandom
); 这允许接收器恢复IV(作为第一个消息块),然后处理该消息,而不管先前的消息是否被发送和接收。同样,如果只是通过简单的“重放攻击”(攻击者发送先前发送的消息的副本),主动攻击者可能会对该方案造成严重破坏。
作为旁注,String.getBytes()
和new String(byte[])
使用平台默认编码,客户端和服务器之间可能有所不同。你最好使用一个明确的字符集,例如UTF-8:message.getBytes("UTF-8")
和new String(decoded_message, "UTF-8")
。
一般来说,安全和狂妄自然并不好。准备放弃你的代码。您真正应该使用标准协议(如SSL / TLS)的主要原因是无法证明安全性。你会告诉某人(例如你的老板)问你什么让你觉得协议是安全的? “Stack Overflow上的一些人告诉过我”?
答案 1 :(得分:0)
我只想指出IV通常不加密。我猜它没什么害处,但没有必要。