Openssl Encryption Random Key&IV- 存储在数据库中

Openssl Encryption Random Key&IV- Store in DB

我已经阅读了很多关于加密的文章,并且知道自 php 7 以来出现了很多新事物。我正在编写两个函数(encrypt 和 decrpyt)来将加密数据存储在我的数据库中。

我了解 openssl 函数的工作原理,但我想知道我是否将其正确存储在我的数据库中,或者我应该安全地说。我的代码如下:

function wm_encryptString($string) {
    $method = 'aes-256-xts';
    $key = random_bytes(16);
    $iv = random_bytes(16);
    $cipherText = openssl_encrypt($string, $method, $key, 0, $iv);
    $cipherText = $key.$iv.$cipherText;
    $cipherText = base64_encode($cipherText);
    return $cipherText;
}

function wm_decryptString($cipher) {
    $cipher = base64_decode($cipher);
    $method = 'aes-256-xts';
    $key = substr($cipher, 0, 16);
    $iv = substr($cipher, 16, 16);
    $cipher = substr($cipher, 32);
    $readableText = openssl_decrypt($cipher, $method, $key, 0, $iv);
    return $readableText;
}

当我运行这两个函数时,它加密和解密都很好。我的具体问题是,是否使用随机字节生成安全的密钥和 IV,并将其附加到安全存储在数据库中的密文中?我正在存储一些敏感信息并希望确保它已安全加密。

我的第二个问题是,我知道我可以使用这些函数加密字符串,但我可以使用相同的函数加密 blob 吗?我将一些文档存储在我的数据库中(我知道你们中的许多人会说永远不要将文档存储在数据库中,但我使用数据库是因为我只存储了一些文档,少于 100 个,并且它使备份更容易)。我可以使用相同的函数加密 blob/file 吗?

任何反馈都将不胜感激,因为我希望我的应用程序尽可能安全。注意我知道我必须采取更多的安全措施来确保我的应用程序是安全的,我的问题是特定于加密的。谢谢你。

  1. 密钥和 IV 的随机字节很好,将 IV 作为加密数据的前缀很好,两者都是安全的选择。

  2. 加密是基于字节的,它不关心任何编码、blob 或其他。对于文本,将字节作为 utf-8.

  3. 为什么选择XTS模式,一般用于磁盘加密?参见 You Dont Want XTS。一般 CBC 或 CTR 模式是正确的选择。请注意,CBC 不要 return 添加错误,CTR 从不使用相同的 IV(计数器初始值)和密钥——很容易出错。

最后,您打算如何保护加密密钥?这是困难的部分。

由于密钥存储在密文旁边,因此该方案不提供任何真正的安全性。相反,它是混淆视听。 默默无闻的安全 一词适用于它。

请记住,密钥是唯一需要保密的部分。这被称为 Kerckhoffs principle。通常假设攻击者能够在服务器被破坏时读取服务器端代码的源代码。在这种情况下,几乎不可能设计出一种密钥对攻击者保密的方案(想想硬件安全模块)。

当然,有不同类型的违规行为。当攻击者只获得对数据库记录的访问权而实际上没有获得 Web 服务器上的 shell 访问权时,您可能会很幸运。当 Web 应用程序没有正确验证和授权请求以及可以从数据库中查询任意信息的错误时,就会发生这种情况(想想 SQL 注入)。
即使在这种情况下,攻击者也可能仅通过查看数据就知道数据是如何加密的(统计所有密文的长度是一个很好的线索)。