【问题标题】:How to switch from AES-256 to AES-128?如何从 AES-256 切换到 AES-128?
【发布时间】:2013-09-27 23:40:28
【问题描述】:

有很多关于 AES 的问题,但我有以下问题。 我目前正在使用以下 AES 实现来加密数据

byte [] PRFkey = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
byte [] plaintext = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

SecretKeySpec encryptionKey=new SecretKeySpec(PRFkey, "AES");
Cipher cipher=Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
byte[] encryptedData=cipher.doFinal(plaintext);

结果结果是 32 字节(256 位)。所以我使用的是 AES-256。这个实现对我来说太慢了。如何切换到 AES-128?我不需要任何填充或操作模式或密钥散列。

提前谢谢你。

【问题讨论】:

  • 注意:为了遵守正常的 Java 命名惯例,PRFkey 不应以大写字母开头。这使它看起来像一个类型的名称。
  • 不要将密钥长度与块大小混淆——AES-256 采用 256 位密钥,但其块大小为 128 位,就像 AES-128 一样。 AES 标准只定义了 128 位块大小,尽管原始 Rijndael 密码也定义了 256 位块大小。

标签: java encryption cryptography aes


【解决方案1】:

您已经在使用 128 位 AES。这取决于您传递给 Cipher.init() 的密钥的长度,在您的示例中为 16 个字节(128 位)。

输出的大小取决于填充模式(以及输入数据的大小)。由于您忽略了指定操作模式或填充,您的 JCE 提供程序可能默认为 "AES/ECB/PKCS5Padding"。 PKCS #5 填充总是会在输出大小上增加一个块,因此您收到的输出是 32 字节而不是 16 字节。

永远不要让您的提供商为您选择默认值。相反,明确指定模式和填充:

Cipher cipher=Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
byte[] encryptedData=cipher.doFinal(plaintext);  // will be 16 bytes

请记住,如果您不指定填充,您的输入数据必须始终是 16 个字节的精确倍数。另请注意,ECB 模式具有相同的明文值将产生相同的密文值的属性。这在密码系统中很少需要。

【讨论】:

    【解决方案2】:

    在堆栈溢出here 上提出了类似的问题,它将帮助您提供您正在寻找的信息。重要的一点是The JCA Reference Guide 说:

    (创建密码对象)如果未指定模式或填充,则使用模式和填充方案的特定于提供程序的默认值。例如,SunJCE 提供程序使用 ECB 作为默认模式,PKCS5Padding 作为 DES、DES-EDE 和 Blowfish 密码的默认填充方案。这意味着对于 SunJCE 提供程序:Cipher.getInstance("DES") 和 Cipher.getInstance("DES/ECB/PKCS5Padding") 是等效的语句。

    因此,由于您仅将“AES”指定为转换,因此 Oracle JDK 7 的 AES 的默认密码是“AES/ECB/PKCS5Padding”,link

    此外,Cipher 类定义了转换“AES/ECB/NoPadding”,它将为您的encryptedData 获得一个非填充的 16 字节值。 ECB 是 AES 的默认模式,您也可以选择“AES/CBC/NoPadding”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-22
      • 1970-01-01
      • 2013-08-12
      • 2013-08-11
      • 2016-06-20
      • 2015-04-10
      • 1970-01-01
      相关资源
      最近更新 更多