Java 我使用AES算法加密32字节长度的数据结果(密文)是64字节长度,这有效吗?

Java 我使用AES算法加密32字节长度的数据结果(密文)是64字节长度,这有效吗?,java,security,encryption,bouncycastle,Java,Security,Encryption,Bouncycastle,我通过java,BouncyCastle提供者实现了这一点 使用块模式=ECB和填充模式=PKCS7填充 我注意到,如果我加密长度为32字节的数据(例如6162616261626162,它是abababababab的十六进制值),我会得到长度为64字节的密码文本(f21ee0564ebd5274e10bf4590594b1e16a19592b917b106f71d41d165289),该密码文本有效吗?从我读到的情况来看,如果加密长度小于32字节的数据,算法会将其填充到32字节长度,并生成一个3

我通过java,BouncyCastle提供者实现了这一点 使用块模式=ECB和填充模式=PKCS7填充

我注意到,如果我加密长度为32字节的数据(例如6162616261626162,它是abababababab的十六进制值),我会得到长度为64字节的密码文本(f21ee0564ebd5274e10bf4590594b1e16a19592b917b106f71d41d165289),该密码文本有效吗?从我读到的情况来看,如果加密长度小于32字节的数据,算法会将其填充到32字节长度,并生成一个32字节长度的密码文本,但是如果你输入的是32字节长度的数据,你不应该收到32字节长度的密码文本吗,此外,如果我输入的数据长度超过32字节,它将正确填充为64字节的密码文本

这就是我的代码的样子:

    public static byte[] encrypt(byte[] plainText, byte[] keyBytes)
        throws GeneralSecurityException {

    SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");

    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
    cipher.init(Cipher.ENCRYPT_MODE, key);

    byte[] cipherText = cipher.doFinal(plainText);

    return cipherText;
}

感谢您的回复

这里解释了PKCS7填充:

它在
1
blockLength
字节之间添加,所有字节都等于填充的大小。这意味着您的消息将被16填充,创建一个32字节的消息,随后用AES编码

请注意,您的消息是16字节,而不是32字节


一般来说,从不使用长度为零的填充,因为无法将其与非零填充区分开来(并且填充必须以可逆方式进行)。

此处解释PKCS7填充:

它在
1
blockLength
字节之间添加,所有字节都等于填充的大小。这意味着您的消息将被16填充,创建一个32字节的消息,随后用AES编码

请注意,您的消息是16字节,而不是32字节


一般来说,从不使用长度为零的填充,因为它无法与非零填充区分开来(填充必须以可逆方式进行)。

您混淆了十六进制字符和字节。两个十六进制字符可用于表示单个字节。因此,您的输入可能是16个字节,然后您的输出变成32个字节。AES是一种128位=16字节的分组密码

PKCS#7填充定义为填充16字节块密码。为了确保纯文本的最后一个字节不会被误认为是填充,PKCS#7填充总是填充。这意味着,在纯文本可被16除的不幸情况下,它将添加整个填充块。填充由指示每个字节中字符串长度的字节字符串组成,因此对于您的情况,填充由以下字节组成,用十六进制表示:
10101010101010101010101010

请注意,Java的默认提供程序使用
“PKCS5Padding”
而不是
“PKCS7Padding”
。虽然PKCS#5仅适用于64位=8字节的块密码,但两者都是相同的。Bouncy Castle也将接受该字符串,因此为了兼容性起见,最好指定
“PKCS5Padding”


没有为使用32字节的AES指定填充,因为它只是一个16字节的分组密码。Rijndael-256是一种32字节的分组密码,它是有意义的,但该算法尚未被NIST标准化,因此应该避免使用。

您混淆了十六进制字符和字节。两个十六进制字符可用于表示单个字节。因此,您的输入可能是16个字节,然后您的输出变成32个字节。AES是一种128位=16字节的分组密码

PKCS#7填充定义为填充16字节块密码。为了确保纯文本的最后一个字节不会被误认为是填充,PKCS#7填充总是填充。这意味着,在纯文本可被16除的不幸情况下,它将添加整个填充块。填充由指示每个字节中字符串长度的字节字符串组成,因此对于您的情况,填充由以下字节组成,用十六进制表示:
10101010101010101010101010

请注意,Java的默认提供程序使用
“PKCS5Padding”
而不是
“PKCS7Padding”
。虽然PKCS#5仅适用于64位=8字节的块密码,但两者都是相同的。Bouncy Castle也将接受该字符串,因此为了兼容性起见,最好指定
“PKCS5Padding”


没有为使用32字节的AES指定填充,因为它只是一个16字节的分组密码。Rijndael-256是一种32字节的分组密码,这对Rijndael-256是有意义的,但该算法尚未被NIST标准化,因此应该避免使用。

由于您的答案不正确,请参阅我的答案以了解原因。@owlstead但32字节确实被填充为64字节。做了一点小小的修改,这样我就不会声称OP的消息是32字节了。你如何解释加上填充后增加了32字节?由于AES的块大小为128位或16字节,因此最多有16字节的填充。@CodesInChaos如果填充为32字节块,则不会。请注意,无法删除已接受的答案。如果您有32字节的块,则它不是AES。由于您的答案不正确,请参阅我的答案以了解原因。@owlstead,但32字节确实被填充为64字节。做了一点小小的修改,这样我就不会声称OP的消息是32字节了。你如何解释加上填充后增加了32字节?由于AES的块大小为128位或16字节,因此最多有16字节的填充。@CodesInChaos如果填充为32字节块,则不会。请注意,不可能删除已接受的答案。如果您有32字节的块,则它不是AES。