我想用数据库上存储过程中使用的MySQL AES_ENCRYPT()
函数进行加密。
首先,在MySQL配置文件中,将加密块模式从aes-128-ecb改为aes-256-cbc .
其次,我的目标是从PHP代码中调用这个存储过程来加密数据(这里是IP和MAC地址)。下图是存储过程。我想知道执行情况是否正确,特别是:
可以用RANDOM_BYTES
为存储过程中的MAC和IP生成IV吗?
可以将IP和MAC的IV存储在表中的另外两个列中吗?
是否可以将密钥存储在具有正确权限的web服务器上的文件中,然后在每个过程调用中将其发送?
下面是调用过程加密数据的PHP代码:
我认为这并不完美,尤其是在没有密钥管理系统的情况下将密钥存储在web服务器上,但我们负担不起。
发布于 2022-10-14 22:01:57
如果你把你的密钥存储在网络主机上,而不是在数据库中,那么你是在防范数据通过其他渠道被窃取的可能性,例如。数据库备份,但访问网络主机是不可能的。
如果IV是使用RANDOM_BYTES
生成和存储在数据库中的,那么您将从数据库中添加熵,并防止对手从web主机窃取密钥和从eg窃取密文的可能性。cookie,但如果没有存储在数据库中的相应IV,则无法解密。
您可以将密钥从加密的光盘存储区解密到ram文件中,例如。/dev/shm/
,并从php
内部引用这一点。或者您可以使用某种网络服务按需提供它,但是在一天结束时,您的php
进程需要向数据库发送一些关键材料,以便它能够完成它的工作。(还有一些商业的外接程序php模块将执行加密的php文件,这也会阻碍尝试。)
到目前为止还不错..。但是静态密钥仍然暴露在面向网络的主机上,这并不理想--如果你也需要在网络主机上解密的话,这是最好的方法。顺便说一句,您还希望能够在某个时候更改静态密钥,并且需要一种方法从用于加密的记录中识别正在使用的密钥。
该计划的一个方面似乎依赖于IVs仍然存在的秘密,但更有可能的是,任何看到静脉注射的人都会认为它是公开的数据,而不是秘密的一部分。因此,您可能会考虑的另一件事是,将网络主机给存储的过程作为关键材料,并在存储的过程中进一步改变它,例如。使用一些键散列(如HMAC
)。(例如HMAC在MySQL中的实现 Pierce'17和Konrad'11.)任何人从网络主机获取密钥,以及从例如加密的数据。单独的db备份,仍将无法解密。(在这种情况下,您需要以某种方式确保HMAC密钥不包含在所述备份文件中。)
另外,您还应该考虑从密文中计算HMAC标记。加密-然后-MAC,并将此存储在记录中。它将确保当您稍后返回解密时,不会在存储中插入密文。
不过,任何能够访问网络主机和数据库的人都将拥有他们所需的一切。如果您不需要解密网络主机上的数据(即。只对日志进行加密和存储),然后您可以在php
中生成一个随机密钥,使用非对称加密保护它,然后将随机密钥以及加密的随机密钥传递到您存储的过程中。(在这一点上,您会想看看sodium_crypto_box
。)
MariaDB -值得注意的是,尽管它与MySQL共享一个公共根,但是MariaDBdoesn't offer AES in CBC mode,只有aes-128-ecb
因此没有使用只调用AES_ENCRYPT
来保护低熵数据的干净方法。另一个复杂的问题是10.10.x之前缺少RANDOM_BYTES
,使得在旧版本的数据库中难以生成加密安全的关键材料。
https://security.stackexchange.com/questions/265493
复制相似问题