kba-team / data-protection
对唯一敏感数据进行确定性单向加密。
Requires
- php: ^7.4|<8.4
- ext-openssl: *
Requires (Dev)
- phpunit/phpunit: ^9.6
README
此类的目标是加密唯一的敏感信息,如社会保险号,在不具有解密可能性的情况下,但仍然能够使用 equals
和 not equals
运算符进行搜索。
场景
数据库中的人的数据包含一个社会保险号。这种数据是敏感的,因为在安全漏洞的情况下,犯罪分子可以使用它来冒充数据库中存储的人的身份。因此,这种信息需要受到保护。
在此场景中,社会保险号永远不会实际显示或处理。它用于识别一个独特的人,即使该人的其他存储数据随时间改变,如婚姻情况下的姓名更改。
假设社会保险号在数据库中不会出现两次。
为了唯一识别一个人,仍然需要能够搜索社会保险号,尽管该信息已被加密。典型的搜索模式是 equals
,在需要唯一识别一个人的情况下,或者 not equals
以避免数据库中同一人的重复条目。
简单地对该信息创建散列值,或者具有静态盐的散列值,不会起作用,因为攻击者可以创建包含所有可能的迭代的彩虹表,并将其散列值与数据库中存储的散列值进行匹配。
创建类似于密码中使用的盐化散列值也不会起作用,因为需要能够在包含数千个条目的数据库中进行搜索。为了执行 equals
搜索,必须使用所有先前使用的盐值对信息进行散列。以这种方式进行的 not equals
搜索不会可靠地确定一个人是否 不在 数据库中。
解决方案
安全存储敏感信息的解决方案是以确定性方式加密它,而不具有解密信息的能力。
安全的加密由一个秘密密钥和一个初始化向量组成,这保证了加密值是唯一的。
根据 Stack Exchange 上的问题 59580 中找到的信息 如何安全存储敏感数据,如社会保险号,CBC 模式下的密码与从明文派生的初始化向量符合确定性加密信息的要求。
为了每次都生成相同的加密值,密钥和使用的密码算法需要对于给定的数据库保持相同,但密钥对于不同的数据库需要不同。这将使攻击者更难创建彩虹表。
缺点
如果秘密加密密钥被泄露,只要计算能力不允许在合理的时间内创建基于所有可能的用秘密密钥加密的社会保险号的彩虹表,加密数据仍然是安全的。
用法
使用 composer 包含此包。
composer require kba-team/data-protection: "^1.0"
安全生成一个秘密密钥。
<?php use kbATeam\DataProtection\SecureSearch; //generate a key $key_hex = SecureSearch::generateKey(); //print the result printf('%s%s', $key_hex, PHP_EOL);
加密数据。
<?php use kbATeam\DataProtection\SecureSearch; //convert the key to its raw version $key_raw = hex2bin($key_hex); //set the social security number $ssn = 1234567890; //encrypt the social security number $ssn_encrypted = SecureSearch::encrypt($ssn, $key_raw); //print the result printf('%s%s', $ssn_encrypted, PHP_EOL);
开发
克隆仓库并使用 composer 安装所有要求。
git clone https://github.com/the-kbA-team/data-protection.git composer install
运行测试。
vendor/bin/phpunit --
MIT 许可证
MIT 许可证
版权所有 (c) 2018 the-kbA-team
本软件及其相关文档文件(以下简称“软件”)的副本获取者,在此免费获得对该软件的使用权,不受限制地处理该软件,包括但不限于使用、复制、修改、合并、发布、分发、许可和/或出售软件副本的权利,并允许向软件提供者提供软件的人这样做,但须遵守以下条件:
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
软件按“原样”提供,不提供任何形式的保证,无论是明示的还是暗示的,包括但不限于适销性、特定用途的适用性和非侵权性保证。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任承担责任,无论这些责任是基于合同、侵权或其他法律行为,以及与软件或软件的使用或其他操作有关。