我刚刚遇到了一个有趣的小问题。
使用Laravel 4,我对一些条目进行加密,然后将它们添加到db中,包括电子邮件地址。
数据库是在默认varchar长度为255的情况下设置的。
我刚刚有一个条目被加密为309个字符,通过切断数据库中的50多个字符来破坏加密。
我已经(暂时)修正了这个问题,只需将varchar长度增加到500个,从理论上讲,这应该可以覆盖我,但我想确定一下。
我不知道加密是如何工作的,但是为了设置我的数据库,是否有一种方法可以从加密输出中判断出最大字符长度?
我是否应该将字段类型从varchar更改为其他类型,以确保不再发生这种情况?
发布于 2015-01-17 13:25:51
结论
首先,请注意,在4.0.0到4.2.16之间(这似乎是最新的版本)发生了相当多的变化。
该方案以42个字符188个字符的惊人开销开始,4.0大约244个字符(考虑到我没有忘记任何新行等等)。因此,为了安全起见,如果明文中的字符编码为单个字节,则可能需要200个字符( 4.2 )和256个字符( 4.0 )加上1.8倍的纯文本大小。
分析
我只是研究了有关这个函数的Laravel 4.0的源代码和Laravel 4.2。让我们先进入大小:
base64_encode(json_encode(compact('iv', 'value', 'mac')))组成(当然,其中的值是基本的64密文,mac是HMAC值)。s::"";中的一个字符串,其中<i>是字符串的大小,<s>是字符串(我在这里假定platform编码的大小)。请注意,我不能100%确定Laravel没有使用任何环绕字符串值的方法,也许有人可以帮我清除掉。
计算
总之,所有的事情都非常依赖于字符编码,对我来说做一个很好的估计是相当危险的。现在假设字节和字符之间存在1:1的关系(例如US):
ceil(len / 3) * 4字符,但是让我们简化一下,对于(len * 4) / 3 + 4来说,64编码的基本IV是44个字符。json_encode在这里不以空格结尾,基数64再次增加相同的开销)好的,我在这里有点累了,但是您可以看到它至少两次用base64编码扩展明文。最后,这是一个增加了相当多开销的方案;他们本可以使用base64(IV|ciphertext|mac)来大幅降低开销。
备注
;结束,所以这并不是必要的;发布于 2015-01-16 20:39:35
@MaartenBodewes‘在解释实际字符串的长度方面做得很好。然而,你永远不可能知道它是肯定的,所以这里有两个选项来处理这种情况。
1.将字段设置为text
将字段从有限的varchar更改为“自扩展”text。这可能是更简单的一个,特别是如果您期望相当长的输入,我肯定会推荐这一点。
2.让你的varchar更长
正如您已经做的那样,根据您期望/允许的输入长度,使您的varchar更长。我会乘以5倍。
但别到此为止!在代码中添加检查以确保数据不被截断:
$encrypted = Crypt::encrypt($input);
if(strlen($encrypted) > 500){
// do something about it
}你能做些什么
您可以将错误写入日志并添加加密数据(这样您可以在扩展DB字段的长度之后手动重新插入数据)。
Log::error('An encrypted value was too long for the DB field xy. Length: '.strlen($encrypted).' Data: '.$encrypted);显然,这意味着您必须频繁地检查日志(或通过邮件将它们发送给您),而且由于DB中的数据不正确,用户在使用应用程序时可能会遇到错误。
另一种方法是抛出一个异常(并向用户显示一个错误),当然还将其写入日志,这样您就可以修复它.
不管怎样,
无论您选择选项1还是选项2,您都应该始终限制输入字段的可接受长度。服务器端和客户端。
https://stackoverflow.com/questions/27991717
复制相似问题