Tag: aes gcm

Java TLS 1.2服务器:AES-GCM解密

我目前正在研究Java TLS服务器。 (几天前我发布了关于KeyExchange签名的post) 我现在正在尝试解密使用AES-GCM编码的TLS消息。 服务器已经处理了CBC,但由于它很容易受到POODLE的影响,我们想要改为使用GCM。 我会尽力解释:) 对于此代码,我们使用的是Java 8u91,Netty 3.9.0。 我们不使用BouncyCastle,我们不打算,我们想坚持使用JDK。 代码 ! /** * Deciphers the fragment and returns the deciphered version of it * * @param fragment * to decrypt * @return the decrypted fragment * @throws InvalidKeyException * @throws InvalidAlgorithmParameterException * @throws IllegalBlockSizeException * @throws BadPaddingException */ private ChannelBuffer decodeCiphered(ChannelBuffer fragment, short contentType, […]

随机访问加密数据AES GCM模式

随机访问AES CTR模式有一个很好的例子,它可以工作: 在android中使用AES CTR模式随机访问InputStream private static final int AES_BLOCK_SIZE = 16; private static IvParameterSpec calculateIVForOffset(final IvParameterSpec iv, final long blockOffset) { final BigInteger ivBI = new BigInteger(1, iv.getIV()); final BigInteger ivForOffsetBI = ivBI.add(BigInteger.valueOf(blockOffset / AES_BLOCK_SIZE)); final byte[] ivForOffsetBA = ivForOffsetBI.toByteArray(); final IvParameterSpec ivForOffset; if (ivForOffsetBA.length >= AES_BLOCK_SIZE) { ivForOffset = new IvParameterSpec(ivForOffsetBA, ivForOffsetBA.length – AES_BLOCK_SIZE, […]

如何将GCM身份validation标记放在密码流的末尾,在解密期间需要内部缓冲?

在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方法抛出一个ShortBufferException #1 。 知道我创建巨大的字节缓冲区是没有用的是非常令人沮丧。 鉴于内部缓冲是所有邪恶的根源,那么我在这里应用的明显解决方案是将文件分成块,每个1 MB – 我从来没有问题发送小文件,只有大文件。 但是,我很难理解为什么内部缓冲首先发生。 以前链接的SO答案说GCM:s认证标签是“在密文末尾添加的”,但它“不必放在最后”这种做法是“弄乱了GCM的在线性质”解密”。 为什么将标签放在最后只会扰乱服务器的解密工作? 这是我的推理方式。 要计算身份validation标记,或者MAC(如果愿意),客户端使用某种哈希函数。 显然, MessageDigest.update()不使用不断增长的内部缓冲区。 然后在接收端,服务器不能做同样的事情吗? 对于初学者来说,他可以解密字节,尽管是未经validation的字节,将这些字节提供给他的哈希算法的更新function,当标签到达时,完成摘要并validation客户端发送的MAC。 我不是一个加密的人,所以请跟我说话,好像我既愚蠢又疯狂,但又爱得足以照顾一些=)我全心全意地感谢你花时间阅读这个问题,甚至可能会有所启发! 更新#1 我不使用AD(关联数据)。 更新#2 编写了使用Java演示AES / GCM加密的软件,以及Java EE中的安全远程协议 (SRP)和二进制文件传输。 前端客户端使用JavaFX编写,可用于动态更改加密配置或使用块发送文件。 在文件传输结束时,会显示一些有关传输文件所用时间和服务器解密时间的统计信息。 该存储库还有一个文档,其中包含我自己的一些GCM和Java相关研究。 享受: […]

Java AES / GCM / NoPadding – 什么是cipher.getIV()给我的?

我在Java 8中使用AES/GCM/NoPadding加密,我想知道我的代码是否存在安全漏洞。 我的代码似乎有效 ,因为它加密和解密文本,但一些细节尚不清楚。 我的主要问题是: Cipher cipher = Cipher.getInstance(“AES/GCM/NoPadding”); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] iv = cipher.getIV(); // ????? IV是否满足“对于给定的密钥,IV不得重复”的要求。 来自RFC 4106 ? 我也很感激我对相关问题的任何答案/见解(见下文),但第一个问题最让我烦恼。 我不知道在哪里可以找到解决此问题的源代码或文档。 这是完整的代码,粗略。 如果我在撰写这篇文章时引入了错误,我深表歉意: class Encryptor { Key key; Encryptor(byte[] key) { if (key.length != 32) throw new IllegalArgumentException(); this.key = new SecretKeySpec(key, “AES”); } // the output is sent to users byte[] encrypt(byte[] […]