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

时间:2012-11-06 10:15:47

标签: java security encryption bouncycastle

我通过java,BouncyCastle Provider实现这一点 使用块模式= ECB和填充模式= PKCS7Padding

我注意到如果我加密具有32字节长度的数据(例如61626162616261626162616261626162这是abababababababab的十六进制值)我得到64字节长度的密文(f21ee0564ebd5274e10bf4590594b1e16a19592b917b19ee106f71d41d165289)这个密文有效吗?从我读到它看起来如果你加密少于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;
}

你的回复

2 个答案:

答案 0 :(得分:3)

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

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

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

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

答案 1 :(得分:1)

这里解释了PKCS7填充: http://en.wikipedia.org/wiki/Padding_(cryptography)#Byte_padding

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

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

通常,永远不会使用零长度的填充,因为它无法与非零填充区分开(并且填充必须以可逆方式完成)。