Laravel 4加密:期望的字符数

TH1*_*981 2 php mysql encryption laravel-4

我刚刚遇到了一个有趣的小问题.

使用Laravel 4,我会在将某些条目添加到数据库之前对其进行加密,包括电子邮件地址.

db的设置默认varchar长度为255.

我刚刚有一个加密到309个字符的条目,通过切断db中的最后50个字符来炸毁加密.

我(暂时)通过简单地将varchar长度增加到500来解决这个问题,理论上应该从这个方面覆盖我,但我想确定.

我不确定加密是如何工作的,但是为了设置我的数据库,有没有办法告诉加密输出期望的最大字符长度?

我应该将我的字段类型更改varchar为其他内容以确保不再发生这种情况吗?

Maa*_*wes 6

结论

首先,要注意的是4.0.0和4.2.16之间有很多变化(这似乎是最新版本).

该方案以令人震惊的开销为188字符开头为4.2,而4.0为约244(假设我没有忘记任何新行等).因此,为了安全起见,如果明文中的字符编码为单个字节,可能需要大约200个字符的4.2和256个字符的4.0加上纯文本大小的1.8倍.

分析

我只是查看了关于这个函数的Laravel 4.0Laravel 4.2源代码.让我们先进入大小:

  1. 数据是序列化的,因此加密大小取决于值类型的大小(可能是一个字符串);
  2. 序列化数据是使用Rijndael 256或AES 填充的PKCS#7 ,这意味着添加1到32个字节或1到16个字节 - 取决于4.0或4.2的使用;
  3. 这个数据用密钥和IV加密;
  4. 密文和IV分别转换为base64;
  5. 计算使用SHA-256而不是base64编码密文的HMAC,返回64字节的小写十六进制字符串
  6. 那么密文由base64_encode(json_encode(compact('iv', 'value', 'mac')))(其中值是基本64密文,mac当然是HMAC值)组成.

在一个字符串PHP是序列化为s:<i>:"<s>";哪里<i>是字符串的大小,并且<s>是字符串(我在这里假设PHP平台编码与问候的大小).请注意,我并不是100%确定Laravel不会使用任何包裹字符串值,也许有人可以为我清除.

计算

总而言之,一切都在很大程度上取决于字符编码,对我来说做出一个很好的估计是相当危险的.让我们假设现在字节和字符之间的关系为1:1(例如US-ASCII):

  1. 序列化最多可为999个字符的字符串添加9个字符
  2. padding最多可添加16或32个字节,我们假设它们也是字符
  3. 加密使数据保持相同的大小
  4. PHP中的base64创建了ceil(len / 3) * 4字符 - 但是为了简化它(len * 4) / 3 + 4,base 64编码的IV是44个字符
  5. 完整的HMAC是64个字符
  6. JSON编码为引号和冒号添加3*5个字符,加上围绕它们的大括号和逗号的4个字符,总共19个字符(我假设json_encode这里没有以空格结尾,基数64再次添加相同的开销

好的,所以我在这里有点累,但你可以看到它至少两次使用base64编码扩展明文.最后,这是一个增加了很多开销的方案; 他们可能只是习惯于base64(IV|ciphertext|mac)严重减少开销.

笔记

  • 如果你现在不在4.2,我会认真考虑升级到最新版本因为4.2修复了很多安全问题
  • 示例代码使用字符串作为键,并且不清楚是否容易使用字节;
  • 文档确实警告Rijndael默认值以外的密钥大小,但忘记提及字符串编码问题;
  • 即使使用了点击率模式,总是会执行填充,这样会破坏目的;
  • 使用PKCS#7填充的Laravel垫,但由于序列化总是似乎结束;,这不是真正必要的;
  • 看到经过身份验证的加密用于数据库加密(IV未使用,在4.2中修复)是一件好事.