繁体   English   中英

在PC和Android之间发送加密数据时,AES / CTR / NoPadding最后一块丢失

[英]AES/CTR/NoPadding last block is lost when sending encrypted data between PC and Android

我正在使用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();
}

我用localhost测试了此代码-一切正常。

当我使用Android设备对其进行测试时,如果未满,则会丢失最后一个块。 因此,如果它是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使用不同的密码提供程序这一事实引起的。

Android使用一个叫做Bouncy Castle的城堡,该城堡在AES / CTR模式下具有一个已知的“错误”。 进行加密/解密时,它将错过最后一个块。 (请参阅其他许多stackoverflow问题)

如果只需要点击率模式。 已知的解决方法是,您可以在Android上自己实现它,方法是“动态”重复生成密钥流块(通过加密0的字节数组),然后将它们与缓冲区进行XOR。

希望这可以帮助

在关闭加密流之前,您是否已完全清除它们? AES以块大小的块处理数据,在CTR模式下,它是密钥流。 如果在关闭流之前没有完全刷新流,则无论是加密还是解密,您都可能会丢失最后一个块。

同样,您需要确保已编写/读取了Android和PC之间传输文件流中的所有内容。 您的最后几条数据可能已经放在文件传输缓冲区中,而该缓冲区关闭时,该缓冲区正等待写入。

Android确实与Java不同,因此我怀疑您的错误可能是在Android方面。 也许尝试Android-> Android以及PC-> PC,只是为了确保Android方面的一切都很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM