该关系取决于您使用的填充和链接模式,以及算法块大小(如果它是块密码)。
一些加密算法是“逐位”(或“逐字节”)加密数据的流密码。它们中的大多数产生一个依赖于密钥的伪随机字节流,并且通过将该流与数据进行异或来执行加密(解密是相同的)。使用流密码,加密长度等于明文数据长度。
其他加密算法是分组密码。名义上,分组密码对固定长度的单个数据块进行加密。AES 是具有 128 位块(16 字节)的块密码。请注意,AES-256 也使用 128 位块;“256”是关于密钥长度,而不是块长度。链接模式是关于如何将数据分成几个这样的块(这并不容易安全地做到这一点,但 CBC 模式很好)。根据链接模式,数据可能需要一些填充,即在末尾添加一些额外字节,以便长度适合链接模式。填充必须能够在解密时明确删除。
在 CBC 模式下,输入数据的长度必须是块长度的倍数,因此习惯上添加 PKCS#5 填充:如果块长度为n,则至少添加 1 个字节,最多n,使得总大小是n的倍数,最后添加的字节(可能全部)具有数值k,其中k是添加的字节数。解密后,只需查看最后一个解密字节即可恢复k,从而知道最终必须删除多少填充字节。
因此,使用 CBC 模式和 AES,假设 PKCS#5 填充,如果输入数据的长度为d,则加密长度为(d + 16) & ~15
。我在这里使用类似 C 的符号;简单来说,长度在d+1和d+16之间,是 16 的倍数。
有一种称为 CTR(作为“计数器”)的模式,其中分组密码加密计数器的连续值,产生伪随机字节流。这有效地将块密码转换为流密码,因此长度为d的消息被加密为d字节。
警告:关于所有加密系统(包括流密码)和模式都需要一个称为IV(初始值)的额外值。每条消息都应有其 IV,使用相同密钥加密的两条消息不得使用相同的 IV。有些模式有额外的要求;特别是,对于 CBC 和 CTR,IV 应使用加密强的伪随机数生成器随机且均匀地选择。IV 不是秘密的,但必须被解密者知道。由于每条消息都有自己的 IV,因此通常需要将 IV 与加密消息一起编码。对于 CBC 或 CTR,IV 的长度为n,因此,对于 AES,这是一个额外的 16 个字节。我不知道 mcrypt 对 IV 做了什么,但是,从密码学上讲,IV 必须在某个时候进行管理。
至于 Base64,它适用于在纯文本媒体上传输二进制数据,但这对于正确的数据库来说不是必需的。另外,Base64 将数据放大了 33% 左右,不宜盲目应用。我认为您最好在这里避免使用 Base64。