Java中的AES算法,加密恰好一个block的时候返回两个block,为什么?
怪我咯
怪我咯 2017-04-17 13:05:24
[Java讨论组]

输入长度小于一个block的时候输出一个block,这没问题,因为做了padding
但为什么输入恰好是一个block(16 bytes)的时候,输出变为2个block(32 bytes),简直无法理解啊

javapublic static void main(final String[] args) throws Exception {
    final byte[] keyBytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
    final SecretKey key = new SecretKeySpec(keyBytes, "AES");
    final Cipher aes = Cipher.getInstance("AES");
    aes.init(Cipher.ENCRYPT_MODE, key);
    final byte[] input = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
    final byte[] result = aes.doFinal(input);
    System.out.println(result.length); // prints 32
    return;
}
怪我咯
怪我咯

走同样的路,发现不同的人生

全部回复(1)
黄舟

你在getInstance时没有指定padding算法,默认采用的是PKCS5Padding
这种padding模式下,如果末位分组缺少n个字节,就补足nn

If numberOfBytes(clearText) mod 16 == 15, PM = M + 0x01
If numberOfBytes(clearText) mod 16 == 14, PM = M + 0x0202
If numberOfBytes(clearText) mod 16 == 13, PM = M + 0x030303
...
If numberOfBytes(clearText) mod 16 == 1, PM = M + (0x0F0F0F...0F0F)
                                                   |---15个0x0F---|

你可能会想,对啊没错啊,如果正好长度是16,不就不用补码了么:

If numberOfBytes(clearText) mod 16 == 0, PM = M + (nothing...)

那么问题来了,我在进行逆操作,比如解密的时候,对于一个已经padding过的末位分组,末尾是 0x0202, 我怎么恢复它padding之前的样子呢?因为可能会有两种情况

  1. 未padding之前就是16字节0x0202结尾
  2. 它本来是14个字节 ,padding之后变成14个字节+ 0x0202 = 16个字节

所以,实际上,如果末尾分组的长度正好等于一个分组长度的话,还需要再补nn,也就是

If numberOfBytes(clearText) mod 16 == 0, PM = M + (0x101010...1010)
                                                   |---16个0x10---|
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号