- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我在 Java 8 中使用 AES/GCM/NoPadding
加密,我想知道我的代码是否存在安全漏洞。我的代码似乎工作,因为它可以加密和解密文本,但有一些细节不清楚。
我的主要问题是:
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] iv = cipher.getIV(); // ?????
该 IV 是否满足“对于给定 key ,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[] src) throws Exception {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] iv = cipher.getIV(); // See question #1
assert iv.length == 12; // See question #2
byte[] cipherText = cipher.doFinal(src);
assert cipherText.length == src.length + 16; // See question #3
byte[] message = new byte[12 + src.length + 16]; // See question #4
System.arraycopy(iv, 0, message, 0, 12);
System.arraycopy(cipherText, 0, message, 12, cipherText.length);
return message;
}
// the input comes from users
byte[] decrypt(byte[] message) throws Exception {
if (message.length < 12 + 16) throw new IllegalArgumentException();
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec params = new GCMParameterSpec(128, message, 0, 12);
cipher.init(Cipher.DECRYPT_MODE, key, params);
return cipher.doFinal(message, 12, message.length - 12);
}
}
假设用户破解我的 key = 游戏结束。
更详细的问题/相关问题:
cipher.getIV()
并使用自己的计数器自己构造一个 IV?cipher.getIV()
的源代码是否可以在线获得?那个 IV 总是 12 字节长吗?
身份验证标签是否总是 16 字节(128 位)长?
使用 #2 和 #3,并且没有填充,这是否意味着我的加密消息总是 12 + src.length + 16
字节长? (所以我可以安全地将它们压缩成一个字节数组,我知道正确的长度?)
在给定用户知道的恒定 src 数据的情况下,向用户显示无限数量的 src 数据加密是否安全?
如果 src 数据每次都不同(例如,包括 System.currentTimeMillis()
或随机数),我向用户显示无限数量的 src 数据加密是否安全?
如果我在加密之前用随机数填充 src 数据会有帮助吗?在前面和后面说 8 个随机字节,还是只在一端?或者这根本没有帮助/让我的加密变得更糟?
(因为这些问题都是关于我自己的代码的同一 block ,并且它们彼此密切相关,并且其他人在实现相同的功能时可能/应该有相同的问题集,因此拆分感觉是错误的问题分成多个帖子。如果这更适合 StackOverflow 的格式,我可以单独重新发布它们。让我知道!)
最佳答案
Q1:cipher.getIV() 返回的 IV 对我这样使用安全吗?
是的,至少对于 Oracle 提供的实现来说是这样。它是使用默认的 SecureRandom
实现单独生成的。因为它的大小是 12 字节(GCM 的默认值),所以你有 96 位的随机性。计数器重复的机会非常小。您可以在 Oracle JDK 所基于的 OpenJDK (GPL'ed) 中查找源代码。
不过,我仍然建议您生成自己的 12 个随机字节,因为其他提供者的行为可能会有所不同。
Q2:IV 总是 12 字节长吗?
这是极有可能的,因为它是 GCM 默认值,但其他长度 对 GCM 有效。然而,该算法必须对 12 字节以外的任何其他大小进行额外的计算。由于弱点,强烈建议将其保持在 12 字节/96 位,API 可能会限制您选择 IV 大小。
Q3:认证标签总是16字节(128位)长吗?
不,它可以具有从 64 位到 128 位的任何字节大小,以 8 位为增量。如果它更小,它只是由身份验证标签的最左边字节组成。您可以使用 GCMParameterSpec
指定其他大小的标签。作为 init
调用的第三个参数。
请注意,GCM 的强度很大程度上取决于标签的大小。我建议将其保持为 128 位。如果您想生成大量密文,96 位应该是最小值尤其是。
Q4:使用#2 和#3,并且没有填充,这是否意味着我的加密消息总是 12 + src.length + 16 字节长? (所以我可以安全地将它们压缩成一个字节数组,我知道正确的长度?)
见上文。对于 Oracle 提供程序,情况就是如此。使用 GCMParameterSpec
确定。
Q5:在给定用户知道的恒定 src 数据的情况下,向用户显示无限数量的 src 数据加密是否安全?
几乎未绑定(bind),是的。大约 2^48 次加密后,我会开始担心。但是,通常您应该设计键更改。
Q6:如果 src 数据每次都不同(例如,包括 System.currentTimeMillis() 或随机数),我向用户显示无限数量的 src 数据加密是否安全?
查看 Q5 和 Q7 的答案
Q7:如果我在加密之前用随机数填充src数据会有帮助吗?在前面和后面说 8 个随机字节,还是只在一端?或者这根本没有帮助/让我的加密变得更糟?
不,这根本没有帮助。 GCM 在下面使用 CTR 模式,所以它只会用 key 流加密。它不会充当 IV。现在,如果您有不断变化的消息要加密,您可以查看 AES-GCM-SIV,但请注意,该算法未在任何 JCA 提供程序中实现。
如果您需要大量密文(高于 2^48!,或 2^32 - ~40 亿 - 谨慎起见),那么我建议您使用该随机数和您的 key 作为 key 派生函数或 KDF . HKDF 目前是同类中最好的,但您可能需要使用 Bouncy CaSTLe 或自己实现。
关于java - 如何处理 "AES/GCM/NoPadding"的 IV 和身份验证标签?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31851612/
对于 Metal ,如果对主纹理进行 mipmap 处理,是否还需要对多采样纹理进行 mipmap 处理?我阅读了苹果文档,但没有得到任何相关信息。 最佳答案 Mipmapping 适用于您将从中
我正在使用的代码在后端 Groovy 代码中具有呈现 GSP(Groovy 服务器页面)的 Controller 。对于前端,我们使用 React-router v4 来处理路由。我遇到的问题是,通过
我们正在 build 一个巨大的网站。我们正在考虑是在服务器端(ASP .Net)还是在客户端进行 HTML 处理。 例如,我们有 HTML 文件,其作用类似于用于生成选项卡的模板。服务器端获取 HT
我正在尝试将图像加载到 void setup() 中的数组中,但是当我这样做时出现此错误:“类型不匹配,'processing .core.PImage' does not匹配“processing.
我正在尝试使用其私有(private)应用程序更新 Shopify 上的客户标签。我用 postman 尝试过,一切正常,但通过 AJAX,它带我成功回调而不是错误,但成功后我得到了身份验证链接,而不
如何更改我的 Processing appIconTest.exe 导出的默认图标在窗口中的应用程序? 默认一个: 最佳答案 经过一些研究,我能找到的最简单的解决方案是: 进入 ...\process
我在 Processing 中做了一个简单的小游戏,但需要一些帮助。我有一个 mp3,想将它添加到我的应用程序中,以便在后台循环运行。 这可能吗?非常感谢。 最佳答案 您可以使用声音库。处理已经自带
我有几个这样创建的按钮: 在 setup() PImage[] imgs1 = {loadImage("AREA1_1.png"),loadImage("AREA1_2.png"),loadImage
我正在尝试使用 Processing 创建一个多人游戏,但无法弄清楚如何将屏幕分成两个以显示玩家的不同情况? 就像在 c# 中一样,我们有Viewport leftViewport,rightView
我一直在尝试使用 Moore 邻域在处理过程中创建元胞自动机,到目前为止非常成功。我已经设法使基本系统正常工作,现在我希望通过添加不同的功能来使用它。现在,我检查细胞是否存活。如果是,我使用 fill
有没有办法用 JavaScript 代码检查资源使用情况?我可以检查脚本的 RAM 使用情况和 CPU 使用情况吗? 由于做某事有多种方法,我可能会使用不同的方法编写代码,并将其保存为两个不同的文件,
我想弄清楚如何处理这样的列表: [ [[4,6,7], [1,2,4,6]] , [[10,4,2,4], [1]] ] 这是一个整数列表的列表 我希望我的函数将此列表作为输入并返回列表中没有重复的整
有没有办法在不需要时处理 MethodChannel/EventChannel ?我问是因为我想为对象创建多个方法/事件 channel 。 例子: class Call { ... fields
我有一个关于在 Python3 中处理 ConnectionResetError 的问题。这通常发生在我使用 urllib.request.Request 函数时。我想知道如果我们遇到这样的错误是否可
我一直在努力解决这个问题几个小时,但无济于事。代码很简单,一个弹跳球(粒子)。将粒子的速度初始化为 (0, 0) 将使其保持上下弹跳。将粒子的初始化速度更改为 (0, 0.01) 或任何十进制浮点数都
我把自己弄得一团糟。 我想在我的系统中添加 python3.6 所以我决定在我的 Ubuntu 19.10 中卸载现有的。但是现在每次我想安装一些东西我都会得到这样的错误: dpkg: error w
我正在努力解决 Rpart 包中的 NA 功能。我得到了以下数据框(下面的代码) Outcome VarA VarB 1 1 1 0 2 1 1 1
我将 Java 与 JSF 一起使用,这是 Glassfish 3 容器。 在我的 Web 应用程序中,我试图实现一个文件(图像)管理系统。 我有一个 config.properties我从中读取上传
所以我一直在Processing工作几个星期以来,虽然我没有编程经验,但我已经转向更复杂的项目。我正在编写一个进化模拟器,它会产生具有随机属性的生物。 最终,我将添加复制,但现在这些生物只是在屏幕上漂
有人知道 Delphi 2009 对“with”的处理有什么不同吗? 我昨天解决了一个问题,只是将“with”解构为完整引用,如“with Datamodule、Dataset、MainForm”。
我是一名优秀的程序员,十分优秀!