使用AES / CTR模拟流密码

时间:2013-04-30 05:22:06

标签: java encryption cryptography aes bouncycastle

我正在编写一个应用程序服务器,我决定使用AES128 / CTR / NoPadding来保护连接,因为它被认为是足够安全的,而不必将字节扩展到块边界,我认为它非常适合到TCP,这在逻辑上是一个无缝流。

问题是Cipher.update()不会返回加密块,直到它有一个完整的16字节块,因为CTR基本上是基于块密码,虽然模拟流密码。我应该从tcp套接字读取数据并在消息到达时立即处理消息,但是我无法检索最新的块,因为它仍在构建并且其大小小于16个字节。我不能等待,因为我们不知道下一条消息何时发送。当然我可以调用Cipher.doFinal()来获取剩余的但这意味着流的结束(连接)和Cipher对象将被重新初始化。

如果有办法偷看结转,我觉得这很好。 CTR只是简单地使用密钥流对纯文本进行异或,因此无论块中的其余字节如何,我都应该能够获得加密数据。这个问题会有一个很好的解决方法吗?我正在考虑编写一个包装器,用零加密假纯文本以提前获取密钥流并手动进行异或,但我不知道其他人是如何解决这个问题的。

更新

我正在开发一个Android应用程序,结果证明这是Dalvik VM的问题。正如Robert和monnand在下面指出的那样,Java SE至少在默认提供程序中没有这个问题。我想我必须编写一个包装类或将模式更改为CFB8来解决这个问题。 (CTR8无效)感谢所有回复!

3 个答案:

答案 0 :(得分:5)

我刚刚使用Oracle Java 1.7在CTR模式下测试了AES,我无法验证您的观察结果:

Cipher c = Cipher.getInstance("AES/CTR/NoPadding");
KeyGenerator kg = KeyGenerator.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, kg.generateKey());
System.out.println(c.update(new byte[1]).length);  // output: 1
System.out.println(c.update(new byte[20]).length); // output: 20

您可能使用缺陷第三方实施,因为“AES128 / CTR / NoPadding”不是我系统上的已知密码。

答案 1 :(得分:4)

我今天遇到了完全相同的问题,并且刚刚解决了这个问题。

问题是您的提供商,可能是Bouncy Castle。当您致电getInstance()时,只需提供算法名称(在我的情况下为“AES / CTR / NoPadding”)。 不要指定提供商。

让代码解释一下:

正如@Robert所说,以下代码正常运行:

Cipher c = Cipher.getInstance("AES/CTR/NoPadding");
KeyGenerator kg = KeyGenerator.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, kg.generateKey());
System.out.println(c.update(new byte[1]).length);  // output: 1
System.out.println(c.update(new byte[20]).length); // output: 20

但是,如果您将提供者指定为“BC”,则会出错:

Cipher c = Cipher.getInstance("AES/CTR/NoPadding", "BC");
KeyGenerator kg = KeyGenerator.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, kg.generateKey());
System.out.println(c.update(new byte[20]).length); // output: 16
System.out.println(c.update(new byte[1]).length);  // null pointer exception

它可以被视为Bouncy Castle的一个bug,或者是一种(奇怪但合理的)功能。

答案 2 :(得分:0)

我自己没有必要解决这个问题,但一种解决方法是手动生成密钥流并自己处理XOR。

也就是说,只要您需要使用密文进行XOR的新数据,就可以从AES/CTR/NoPadding切换到AES/ECB/NoPadding并重复加密incrementing counter value

远非理想,但我认为它会起作用。