提问者:小点点

如果我们用AES密钥包装256位AES密钥,那么包装密钥的大小可以超过32字节?


我有一段代码,其中我用AES密钥包装我的对称密钥(AES):

  1. swkKey:这是用于包装的AES密钥。
  2. key:要包装的密钥。

代码:

SecretKey swkKeySpec = new SecretKeySpec(swkKey, 0, swkKey.length, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
final int ivLength = 12;
final IvParameterSpec iv = createIV(ivLength);///Creates a new array.
cipher.init(Cipher.WRAP_MODE, swkKeySpec, iv);
SecretKey sKeySpec = new SecretKeySpec(key, 0, key.length, "AES");
byte[] wrappedAppKey = cipher.wrap(sKeySpec);`

如果key为256位,swkkey为256位,则wrappeAppKey的长度是多少。包装密钥可以超过32字节吗?请注意,在这种情况下,我收到以下日志:

key length: 32(key to be wrapped)
swkKey length: 32(key used to wrap)
wrappedAppKey size: 48(final wrapped key output).

共1个答案

匿名用户

使用标准操作模式的包装密钥只是密钥编码数据的加密。由于AES密钥的编码数据与原始数据相同,256位密钥的数据仅为32字节。

这些非专用模式(如GCM/CBC/ECB)的主要区别在于密钥字节的处理方式:它们直接在SecreKey实例中使用,而不是作为字节返回。这非常重要,特别是如果操作是在硬件(智能卡、HSM、TPM)而不是软件中执行的;包装密钥的字节可以在专用设备中保存/保护。

GCM在下面使用CTR模式,这是一种流操作模式。流操作模式不需要对明文进行填充,因此密文也将简单地为32字节。Java还将身份验证标签(t)包括在计算中。默认情况下GCM使用最大身份验证标签大小,即16字节,因此将其添加到密钥本身的密文中,为您留下48字节。可以使用更专业的GCMParameterSpec类而不是ivParameterSpec来配置标签大小;请注意,较小的标签大小可能会为GCM模式引入漏洞。

但是,请记住,还需要能够重新生成IV/nonce以进行GCM模式加密。因此,如果无法从上下文中重新生成,您也需要存储它。还要注意,如果将nonce重复用于相同的包装密钥,GCM模式会以可怕的方式中断。大多数时候,使用完全随机的随机数,因此将其与密文一起存储非常重要。GCM强烈建议使用12字节的随机数,将密文扩展到60字节。

或者可以使用SIV模式或GCM-SIV模式。这些模式将身份验证标签用作“合成”IV。这使得加密具有确定性(相同的明文导致相同的密文)。由于密钥本身应该是随机的,它们对于这种模式非常有用,因为它们不需要使用RNG或存储IV。不幸的是,通用密码库通常不包含这些模式的实现。