java - PC 和 Android 之间发送加密数据时 AES/CTR/NoPadding 最后一 block 丢失

标签 java android sockets aes encryption

我使用 AES/CTR/NoPadding 算法来加密 PC 和 Android 之间使用套接字发送的数据。

我编写了单元测试,它向 Android 设备发送 [1;512] 字节并接收回相同的数据 - echo 服务。接收到的数据必须等于发送的数据。

测试客户端:

for (int n = 1; n <= 512; n++) {
... skip ...
    try {
        Object connection = socketFilter.openConnection(socket);
        in = new CipherInputStream(socket.getInputStream(), encryptor);
        out = new CipherOutputStream(socket.getOutputStream(), decryptor);

        byte buf[] = new byte[n];
        byte received[] = new byte[n];

        TestUtils.numbers(buf);

        out.write(buf, 0, buf.length);
        socket.shutdownOutput();

        int len = in.read(received, 0, received.length);

        if (buf.length != len) {
            System.err.println("Expected: " + buf.length + " but was: " + len);
        }
    }
    finally {
        ... skip close streams ... 
    }

}

回显服务器:

Socket clientSocket = socket.accept();
CipherInputStream in = new CipherInputStream(clientSocket.getInputStream(), decryptor);
CipherOutputStream out = new CipherOutputStream(clientSocket.getOutputStream(), encryptor);

try {
    byte buf[] = new byte[512];
    int len;

    if ((len = in.read(buf)) > 0) {
        out.write(buf, 0, len);
        out.close();
    }
}
finally {
    in.close();
    out.close();
}

我用本地主机测试了这段代码 - 一切正常。

当我使用 Android 设备测试它时,如果最后一个 block 未满,则会丢失。 因此,如果是 30 字节,则仅收到 16 字节。

来自测试的消息:

... skip ...
Expected: 30 but was: 16
Expected: 31 but was: 16
Expected: 33 but was: 32
... skip ...
Expected: 207 but was: 192
Expected: 209 but was: 208
Expected: 210 but was: 208
... skip ...

可能出了什么问题?

最佳答案

看来该问题是由于 Android 和 Hotspot JVM 使用不同的 Cipher Provider 造成的。

Android 使用名为 Bouncy CaSTLe 的工具,该工具在 AES/CTR 模式下存在已知“错误”。进行加密/解密时,它会错过最后一个 block 。 (查看许多其他 stackoverflow 问题)

如果您只想要 CTR 模式。已知的解决方法是您自己在 Android 上实现它,方法是“即时”重复生成 key 流 block (通过加密 0 的字节数组),并将它们与缓冲区进行异或。

希望这有帮助

关于java - PC 和 Android 之间发送加密数据时 AES/CTR/NoPadding 最后一 block 丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21220878/

相关文章:

Java网络文件传输问题

java - 如何在 Java 中使用 try 和 catch 进行异常处理后恢复代码

java - 改善月球车的运动

java - Android持久化有什么用?

java - ArrayList.filter 不起作用

android - 使背景继承自 selectableItemBackground

c++ - Windows 8 下未解析的套接字引用

java - 如何知道已经建立的连接的状态?

Java搜索表单查询IP号码

java - Spring Mongo的查找操作在windows server 2008机器上卡住