【问题标题】:PHP MySQL - on the fly encrypt decrypt data without storing the keyPHP MySQL - 在不存储密钥的情况下动态加密解密数据
【发布时间】:2011-04-20 14:42:34
【问题描述】:

我已经解决了几个关于此的 SO 问题,我的方法在想要加密数据方面有点不同。这就是我想做的事情..

基本上我所有的客户数据都存储在数据库中,3 周或 4 周后,我不再需要他们的数据,例如地址、城市、州、邮编、电话、电子邮件地址、他们订购的产品等。

现在这些数据以原始格式存储在数据库 (mysql) 中。

我在想的是,在某些日子之后,我将加密驻留在 mysql 数据库中的所有数据,而不是存储密钥,我将每次通过输入框手动输入它(当想要加密它或者如果出于某种原因解密它只是为了显示在屏幕上)。

所以基本上这就是它的工作原理..

1) 选择客户在mysql中的记录

2) 通过输入框获取加密密钥

3) 通过加密数据更新mysql记录

这是我的两个问题...

1) 从某种意义上说,如果数据库被破坏,数据将得到保护,上述策略是否是一个好的策略。此外,如果入侵者要获得对代码的访问权限,他们将无法访问密钥,因为它不会存储在任何 php 文件中的任何位置。

2) 我应该如何设置加密系统?我应该使用mysql的函数AES_ENCRYPT吗(请记住,数据的长度可能会有所不同,例如地址,电子邮件地址或有关客户的其他一些信息)

【问题讨论】:

    标签: php mysql encryption


    【解决方案1】:

    这个方案听起来会很好用。您只需要注意一些细节。

    AES_ENCRYPT(这很好——这也适用于您可能使用的任何其他加密方法)返回一个二进制字符串。您需要将其存储在可以保存二进制字符串(BINARYVARBINARYBLOB 变体)的列中,而您可能将预加密信息存储在非二进制字符串列中。因此,您要么需要另一组用于加密信息的列,要么使用一些基于文本的编码,以便能够将加密数据放在用于未加密形式的相同列中。

    此外,您在应用程序逻辑中应该非常小心,以免意外地用未加密的数据重新填充加密行(想想查看记录 -> 解密 -> 保存更改等场景)。

    最后,如果坏人对您的服务器/应用程序具有写入权限,那么他们很可能会截获加密密钥并保存它。由于所有记录的密钥可能都是相同的(由于密钥管理考虑),这足以让他们获取您的所有数据。但是,如果他们只管理读取访问权限,那就太好了。

    【讨论】:

    • 还要注意 MySQL 的 AES 实现使用空填充,这与其他 AES 实现使用的 default 填充机制不同。如果您需要在没有 MySQL 帮助的情况下解密 AES 的 blob,这可能会很麻烦。
    • @Jon:感谢您的详细回复。我不知道加密数据不能存储在同一列中。您能否详细说明如何将加密数据存储在同一列中?谢谢
    • @Adil:您需要使用仅使用可打印字符的编码进一步对密文进行编码。 base64 是个不错的选择:php.net/manual/en/function.base64-encode.php
    • @Jon:如果您对数据库进行所有加密/解密,则不需要 base64。二进制列对不可打印的值非常满意。如果您曾经将它们视为字符串(例如,用于显示,或包装在 URL 或 XML 文档中发送),则只需要对它们进行 base64 编码。在这种情况下,这听起来不会发生。
    • @CameronSkinner:请仔细阅读答案。如果您想将密文存储在之前用于明文的同一列中,则需要 base64,因为那将 不是 是二进制列。
    【解决方案2】:

    Public-key cryptography 可能是比 AES 更好的选择。它使用两个键而不是一个。使用公钥加密的数据只能由私钥解密。这意味着您不必太担心公钥会落入坏人之手,因为实际上无法使用它来解密任何数据。

    PHP 对于公钥加密的最佳选择是standard OpenSSL extension,它使用行业标准的RSA 系统。

    密钥可以存储在PEM-encoded (fancy base64) 文件中,requires a passphrase 可以解锁。您希望提示用户输入的是这个密码,而不是实际的密钥。这是幸运的,因为安全的 RSA 密钥相当大,无法完全记住。这也让您可以将私钥安全地存储在服务器上。

    此外,这应该很明显,但您可能希望确保通过 SSL 为您的应用程序提供服务,即使这是一个完全内部的应用程序。在不保护数据传输的情况下保护数据是愚蠢的。

    【讨论】:

    • 我不确定公钥加密在这里是否合适。 OP 是在谈论一个封闭的系统,而 PKC 是为不想共享秘密的各方设计的。您的想法的好处是可以更改密码而无需重新加密所有数据,因此 +1。
    • @Cameron,他主要担心的似乎是他不希望在没有人力的情况下进行数据解密。用于加密的公钥和受密码保护的私钥将实现该目标,即使您完全正确地认为这是对技术的滥用。
    • 我同意,这是个好主意。我建议妥协:)
    【解决方案3】:

    您还应该考虑在发生攻击时如何更改密码。 @Charles 的想法很适合这一点,但使用 RSA 加密实际数据可能会很慢(公钥算法比对称密码慢得多)。

    我建议您在 Charles 的建议和您最初的想法之间做一些事情。存储单个加密密钥,但请确保该密钥已使用密码进行加密。使用单一密钥加密您的数据。当用户想要解密数据时,他们可以输入密码以访问密钥。

    您现在可以随时更改密码,无需更改加密密钥,也无需重新加密所有数据。

    AES 是实际加密工作的不错选择。它速度很快,并且经过充分研究。

    【讨论】:

      【解决方案4】:

      我不确定这是否适合您,但上个月在 RSA 上,有一家公司在 Linux 上为 mySQL 提供透明数据加密。他们还有一种方法来管理和存储密钥,以便它们与数据分开。适用于 PCI、HIPAA-HITECH 等...

      它们在 mySQL 写入时加密到磁盘,并在请求数据时解密。应用程序或数据结构完全没有变化。公司是Gazzang。只需搜索它们,或查看 RSA Innovation Sandbox 2011。

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 2011-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-01
        • 2022-08-24
        • 1970-01-01
        • 2015-02-01
        • 1970-01-01
        相关资源
        最近更新 更多