加密问题

时间:2017-06-26 00:45:36

标签: php mysql codeigniter encryption cryptography

asked a question here我设法部分实施建议。在我删除aes-256加密并且保留aes-128(默认)codeigniter加密后,数据现在以二进制字段(varbinary(500))加密存储。

但是,我有一些问题,而且我找不到答案,因为我找不到很多关于这个问题的文章,所以如果有人能回答我的问题,或者指点我的书,或任何其他文献为了进一步阅读,我将非常感激。

  1. 为什么加密数据必须存储在二进制类型字段中?将它存储在longtext或varchar中有什么问题?这会使加密变得毫无价值吗?

  2. 为什么我必须首先对变量进行编码,然后在将数据存储在二进制类型的字段中时对其进行加密,当我将数据存储在varchar字段中时,我不必这样做? / p>

    base64_encode($clientName);
    
    $encClientName = $this->encryption->encrypt($clientName);
    
  3. 在我之前的问题中(请参阅顶部的链接)我被建议使用nonce。由于我不知道如何在codeigniter库中使用它,我没有实现该部分。这会使我的数据安全性降低吗?任何人都可以在codeigniter上发布任何使用nonce的代码段吗?

  4. 再次,非常感谢任何关于此主题阅读材料的链接(使用php将加密数据存储在数据库中)。

2 个答案:

答案 0 :(得分:6)

  

为什么加密数据必须存储在二进制类型字段中?将它存储在longtext或varchar中有什么问题?这会使加密变得毫无价值吗?

加密数据是二进制的。它经常包含在文本编码中无效的字节序列,这使得它们无法插入到需要字符串的列中(如VARCHAR或TEXT)。

您可能想要的数据类型是VARBINARY(类似于VARCHAR,但不是字符串)或BLOB(同样,但对于TEXT,还有MEDIUMBLOB,LONGBLOB等)。

  

为什么我必须首先对变量进行编码,然后在将数据存储在二进制类型的字段中时对其进行加密,当我将数据存储在varchar字段中时,我不必这样做?

你没有。这是倒退。

如果您打算使用字符串类型列存储加密数据,则可以通过Base64编码加密后的数据来“伪造”它。但是,您最好使用二进制类型的列,此时您不需要任何其他编码。

  

在我之前的问题中(请参阅顶部的链接)我被建议使用nonce。由于我不知道如何使用codeigniter库,我没有实现该部分。这会使我的数据安全性降低吗?

根据我在文档中看到的内容,我认为CodeIgniter Encryption库默认为您处理。你不应该做任何额外的事情。

答案 1 :(得分:4)

除了duskwuffs的答案之外,我还从一个更加密码相关的角度介绍了你的问题。在我做之前他只是设法发布了一分钟:)

由于Character Encodings的工作方式,加密数据必须存储在二进制类型字段中。我建议您阅读,如果您还没有,this excellent article by Joel Spolsky详细说明了这一点。

重要的是要记住加密算法对原始二进制数据进行操作。也就是说,一个比特串。文字1和0可以用多种方式解释。您可以将此数据表示为无符号字节值(255,255),十六进制(0xFF,0xFF),无论如何,它们实际上只是位于下方的位串。加密算法的另一个属性(或者至少是好的)是加密的结果应该与随机数据无法区分。也就是说,给定一个加密文件和一串CSPRNG生成的长度相同的随机数据,你应该无法确定哪个是哪个。

现在假设您希望将此数据存储在需要UTF8字符串的字段中。因为我们存储在这个字段中的位字符串可能包含任何可能的字节序列,如上所述,我们不能假设我们存储的字节序列将表示实际有效的UTF8字符。这意味着编码为UTF8然后解码回二进制的二进制数据不能保证为您提供原始二进制数据。事实上,它很少会。

你的第二个问题也与编码有关,但这里的编码是base64。 Base64是一种与二进制数据非常相似的编码(事实上,它是专为二进制数据设计的)。 Base64是一种在大多数实现中使用公共字符(a-z,A-Z,0-9和+,/)表示二进制数据的方法。我愿意打赌您正在使用的encrypt函数使用base64_decode或其调用的函数之一。您应该感兴趣的是encrypt函数的输出是否是base64字符串或实际二进制数据,因为这会影响您在数据库中使用的数据字段的类型(例如binary vs varchar)

我相信您在上一个问题中表示您使用了点击率,因此以下内容仅适用于点击率使用的随机数。

CTR的工作原理是加密计数器值,然后将此加密计数器值与您的数据进行对比。这个计数器值由两个部分组成,即nonce和计数器的实际值,通常从0开始。技术上,你的nonce可以是任何长度,但我相信一个常见的值是12个字节。因为我们正在讨论AES,所以计数器值的总大小应该是16个字节。也就是说,12个字节的随机数和4个字节的计数器。

这是重要的部分。每个加密操作都应该:

  • 生成一个新的12字节随机数,用于该操作。
  • 您的实施应添加计数器并执行实际加密。
  • 获得最终密文后,将nonce添加到此密文,以使结果长度为len(ciphertext) + 12)个字节。
  • 然后将此最终结果存储在您的数据库中。

使用静态随机数重复一个随机数,或使用一个12字节的随机数执行超过2 ^ 32次加密操作将使您的密文容易受到攻击。