有很多关于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?我不需要任何填充或操作模式或密钥散列。
提前谢谢。
答案 0 :(得分:3)
您已使用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模式具有相同的明文值将产生相同的密文值的属性。这在加密系统中很少需要。
答案 1 :(得分:1)
在堆栈溢出here上询问了一个类似的问题,它将帮助您提供所需的信息。重要的一点是The JCA Reference Guide说:
(创建密码对象)如果未指定模式或填充,则使用模式和填充方案的特定于提供程序的缺省值。例如,SunJCE提供程序使用ECB作为默认模式,PKCS5Padding作为DES,DES-EDE和Blowfish密码的默认填充方案。这意味着在SunJCE提供程序的情况下:Cipher.getInstance(“DES”)和Cipher.getInstance(“DES / ECB / PKCS5Padding”)是等效语句。
因此,由于您只是将“AES”指定为转换,因此AES for Oracle JDK 7的默认密码为“AES / ECB / PKCS5Padding”,link。
此外,Cipher类定义了转换“AES / ECB / NoPadding”,它将为您的encryptedData
提供非填充的16字节值。 ECB是AES的默认模式,您也可以选择“AES / CBC / NoPadding”。