代码之家  ›  专栏  ›  技术社区  ›  kander

AES中输入与密文长度的关系

  •  14
  • kander  · 技术社区  · 14 年前

    最近开始在我的应用程序中使用密码学,我发现自己对输入文本长度和它产生的密文之间的关系感到困惑。在应用加密之前,很容易确定数据库列的大小。但是,现在列的大小略有不同。

    两个问题:

    1. 我假设这是由于输入的填充,所以它符合密码的要求,对吗?

    蒂亚!

    补充:我使用的密码是AES/Rijndael-256-这种关系在可用的算法之间是否有所不同?

    3 回复  |  直到 14 年前
        1
  •  31
  •   Thomas Pornin    14 年前

    关系取决于 衬垫 连锁 您正在使用的模式,以及算法块大小(如果是块密码)。

    串流加密 它“逐位”(或“逐字节”)加密数据。它们中的大多数产生一个伪随机字节的密钥相关流,加密是通过将该流与数据异或(解密是相同的)来执行的。对于流密码,加密长度等于纯数据长度。

    分组密码 . 一种分组密码,名义上是对一个固定长度的数据块进行加密。AES是一种具有128位块(16字节)的分组密码。请注意,AES-256还使用128位块;“256”表示密钥长度,而不是块长度。这个 链接模式 衬垫 ,即在末尾添加几个额外字节,以便长度适合链接模式。填充物必须能 解密时明确删除。

    在CBC模式下,输入数据的长度必须是块长度的倍数,因此通常添加PKCS#5填充:如果块长度为 ,则最多添加至少1个字节 ,使总大小为 ,最后添加的字节(可能全部)具有数值 k 哪里 k 是添加的字节数。解密后,只需查看要恢复的最后一个解密字节即可 从而知道最终必须删除多少填充字节。

    d 那么加密的长度是 (d + 16) & ~15 . 我在这里使用的是类似C的表示法;简单地说,长度介于 d+1级

    有一种称为CTR(作为“计数器”)的模式,其中分组密码对计数器的连续值进行加密,从而产生伪随机字节流。这有效地将分组密码转换为流密码,从而生成长度为的消息 d d

    警告: 关于所有加密系统(包括流密码)和模式都需要一个称为 (初始值)。每条报文都应有其IV,使用同一密钥加密的两条报文不能使用同一个IV。某些模式有额外的要求;特别是对于CBC和CTR,IV应使用加密强的伪随机数发生器随机、统一地选择。IV不是秘密,但必须被解密者知道。由于每条消息都有自己的IV,因此通常需要将IV与加密消息一起编码。对于CBC或CTR,IV具有长度 n

    至于Base64,它适合在纯文本媒体上传输二进制数据,但对于正确的数据库来说,这应该不是必需的。另外,Base64将数据放大了33%,因此不应盲目应用。我想你最好不要在这里打64垒。

        2
  •  1
  •   user187291    14 年前

    据我所知,在块模式(cbc,ecb)中,输出长度将四舍五入到块大小,由mcrypt\u enc\u get\u block\u size返回。另外,您需要将IV与数据一起存储,因此大小将被舍入strlen(data)+mcrypt\u enc\u get\u IV\u size()。

    至于base64编码,我不必费心(但在转储数据库时一定要使用十六进制编码)。

        3
  •  1
  •   Raj    14 年前

    对于带PKCS#5填充的AES-CBC分组密码,

    #define BLOCKSIZE 16
    
    size_t CipherTextLen = (PlainTxtLen / BLOCKSIZE + 1) * BLOCKSIZE;
    

    这不考虑初始化向量

    推荐文章