相关疑难解决方法(0)

如何将GCM身份验证标记放在密码流的末尾,在解密过程中需要内部缓冲?

在Java中,"默认"AES/GCM提供程序SunJCE将在解密过程中内部缓冲1)用作输入的加密字节或2)作为结果产生的解密字节.执行解密的应用程序代码会注意到Cipher.update(byte[])返回一个空字节数组并Cipher.update(ByteBuffer, ByteBuffer)返回写入长度为0.然后当进程完成时,Cipher.doFinal()将返回所有已解码的字节.

第一个问题是:缓冲哪个字节,上面的数字1或数字2?

我假设缓冲仅在解密期间发生而不是加密,因为首先,在我的Java客户端执行从磁盘读取的文件的加密时,不会发生由此缓冲引起的问题(很快描述),它总是发生在服务器端,接收这些文件并进行解密.其次,它是这么说的这里.仅根据我自己的经验判断,我无法确定,因为我的客户使用了CipherOutputStream.客户端未明确使用Cipher实例上的方法.因此,我无法推断是否使用了内部缓冲,因为我无法看到更新和最终方法返回的内容.

当我从客户端传输到服务器的加密文件变大时,我出现了真正的问题.我的意思是超过100 MB.

那么接下来就是Cipher.update()抛出一个OutOfMemoryError.显然由于内部缓冲区的增长和增长.

此外,尽管内部缓冲并且没有从Cipher.update()接收到结果字节,但Cipher.getOutputSize(int)会不断报告不断增长的目标缓冲区长度.因此,我的应用程序代码被迫分配一个不断增长的源ByteBuffer,它被输入Cipher.update(ByteBuffer,ByteBuffer).如果我试图欺骗并传入一个容量较小的字节缓冲区,那么update方法会抛出一个#1.知道我创建巨大的字节缓冲区是没有用的是非常令人沮丧.ShortBufferException

鉴于内部缓冲是所有邪恶的根源,那么我在这里应用的明显解决方案是将文件分成块,每个1 MB - 我从来没有问题发送小文件,只有大文件.但是,我很难理解为什么内部缓冲首先发生.

以前链接的SO答案说GCM:s认证标签是"在密文末尾添加的",但它"不必放在最后"这种做法是"弄乱了GCM的在线性质"解密".

为什么将标签放在最后只会扰乱服务器的解密工作?

这是我的推理方式.要计算身份验证标记或MAC(如果您愿意),客户端将使用某种哈希函数.显然,MessageDigest.update()不使用不断增长的内部缓冲区.

然后在接收端,服务器不能做同样的事情吗?对于初学者,他可以解密字节,尽管是未经验证的字节,将其提供给他的哈希算法的更新功能,当标签到达时,完成摘要并验证客户端发送的MAC.

我不是一个加密的人,所以请跟我说话,好像我既愚蠢又疯狂,但又爱得足以照顾一些=)我全心全意地感谢你花时间阅读这个问题,甚至可能会有所启发!

更新#1

我不使用AD(关联数据).

更新#2

编写了使用Java演示AES/GCM加密的软件,以及Java EE中的安全远程协议(SRP)和二进制文件传输.前端客户端使用JavaFX编写,可用于动态更改加密配置或使用块发送文件.在文件传输结束时,会显示一些有关传输文件所用时间和服务器解密时间的统计信息.该存储库还有一个文档,其中包含我自己的一些GCM和Java相关研究.

享受:https://github.com/MartinanderssonDotcom/secure-login-file-transfer/


#1

有趣的是,如果执行解密的服务器本身不处理密码,而是使用a CipherInputStream,则不会抛出OutOfMemoryError.相反,客户端设法通过线路传输所有字节,但在解密过程中某处,请求线程无限期挂起,我可以看到一个Java线程(可能是同一个线程)完全利用CPU核心,同时保留文件磁盘不可访问且报告的文件大小为0.然后经过相当长的时间后,Closeable源被关闭,我的catch子句设法捕获由以下原因引起的IOException:"javax.crypto.AEADBadTagException:输入太短 - 需要标记" .

让这种情况变得奇怪的是,使用完全相同的代码传输较小的文件完美无瑕 - 所以显然可以正确验证标签.该问题必须具有与明确使用密码时相同的根本原因,即不断增长的内部缓冲区.我无法在服务器上跟踪成功读取/解密的字节数,因为只要读取密码输入流开始,编译器重新排序或其他JIT优化就会使我的所有日​​志记录都消失得无影无踪.它们[显然]根本没有被执行.

请注意,此GitHub项目及其相关的博客文章称CipherInputStream已损坏.但是,当使用Java 8u25和SunJCE提供程序时,此项目提供的测试不会失败.正如已经说过的那样,只要我使用小文件,一切都适合我.

java encryption cryptography aes aes-gcm

4
推荐指数
1
解决办法
4906
查看次数

标签 统计

aes ×1

aes-gcm ×1

cryptography ×1

encryption ×1

java ×1