5

我正在尝试为将存储有关其客户的机密数据的用户建立一个平台。上下文非常简单:法国法律禁止我访问我的用户将存储的数据(例如患者的医疗记录)。

因此,当用户提交将存储在数据库中的数据时,他应该是唯一有权访问该信息的人。例如,用他的密码对其进行加密。这样,如果我登录到 mysql,我只会看到加密的废话,而看不到可读数据。

我的哲学,可能是错误的,是边做边学。希望你们对我的方法没问题。

问题是:我不知道从哪里开始,怎么做......实际上甚至不知道在谷歌上搜索什么。例如,我什至试图在 codecanyon.net 上找到合适的东西,但不喜欢任何相关的脚本。

提前致谢 :) !

PS:我实际上会对文件有同样的问题(jpg、word、pdf、xls ......这对用户来说应该足够了)。但那是另一回事了。

4

3 回答 3

6

虽然我不熟悉法国的数据保护法,但我确实对欧盟的一般立法有一些经验。可能您必须以这种方式加密系统中的个人数据,以至于无法识别该人。这意味着,技术数据(例如表中的系统特定 ID)可以保持未加密状态。这是我相信你可以真正做到这一点的唯一原因。有点。您必须与律师合作,以确定哪些数据可以保持未加密状态以遵守法律,并且仍然能够为您的客户提供有价值的服务。

但是,我认为您遗漏了重要的一点:如果您无法访问某些数据,那么该数据不得以纯格式到达您的组织。时期。如果是这样,那么您已经可以访问它了。因此,php(或任何类型的基于服务器的加密)或基于 mysql 的加密解决方案是不可能的。

我能想到的唯一解决方案是与第 3 方 PKI 提供商合作,他们将为您的客户提供证书(可能在芯片卡上),并且您的应用程序的客户端在之前加密客户端上的敏感个人数据项它们被发送到您的服务器,并在客户端上解密这些数据项。这也意味着如果您希望该系统基于 Web,则必须在客户端使用一些插件。可能您需要一些签名的 Java 应用程序来管理读卡器和证书。

该设置对您的客户有两个缺点:

  1. 他们处理的不是单一的供应商,因为 PKI 供应商必须是独立的第三方。您不得管理证书。
  2. 如果存储的数据被损坏,加密数据将丢失。因此,您将不得不实施一些疯狂的备份和恢复解决方案。
于 2015-10-07T01:43:54.877 回答
2

所以假设问题如下:

  • 您需要在存储数据之前对其进行加密。
  • 你不应该有解密它的密钥,只加密它。

这实际上有一个工具:它被称为密封 API,它可以通过 OpenSSL 或 Libsodium 来完成。

使用 Libsodium 在 PHP 中密封/解封数据

$store_me = \Sodium\crypto_box_seal(
    $plaintext,
    $recipient_public_key
);

$visible = \Sodium\crypto_box_seal_open(
    $store_me,
    $recipient_keypair
);

使用 OpenSSL 在 PHP 中密封/解封数据

/**
 * A human-usable variant of openssl_seal()
 * 
 * @param string $plaintext Your message
 * @param string $publickey_string PEM-encoded RSA public key
 * @param boolean $encode Hex-encode the output?
 * 
 * @return string
 */
function easy_seal($plaintext, $publickey_string, $encode = false)
{
    $pubkey = openssl_get_publickey($publickey_string);
    if ($pubkey === false) {
        throw new Exception('Could not load public key');
    }
    $sealed = '';
    $ekeys = [];
    $result = openssl_seal($plaintext, $sealed, $ekeys, [$pubkey]);
    if ($result === false) {
        throw new Exception('openssl_seal failed!');
    }
    if ($encode) {
        return json_encode([
            bin2hex($sealed), 
            bin2hex($ekeys[0])
        ]);
    }
    return json_encode([$sealed, $ekeys[0]]);
}

/**
 * Inverse operation of easy_seal()
 * 
 * @param string $ciphertext (the output of easy_seal())
 * @param string $privatekey_string PEM-encoded RSA private key
 * @param boolean $encoded Do we need to decode from hex?
 * 
 * @return string
 */
function easy_unseal($ciphertext, $privatekey_string, $encoded = false)
{
    list($sealed, $ekey) = json_decode($ciphertext, true);
    if ($encoded) {
        $sealed = hex2bin($sealed);
        $ekey = hex2bin($ekey);
    }
    $open_data = '';
    $privkey = openssl_get_privatekey($privatekey_string);
    if ($privkey === false) {
        throw new Exception('Could not load public key');
    }

    $result = openssl_open($sealed, $open_data, $ekey, $privkey);
    if ($result === false) {
        throw new Exception('openssl_open failed!');
    }
    return $open_data;
}

使用示例

$public_key = file_get_contents('/path/to/publickey.pem');
$plaintext = 'Something something dark side';
$store_me = easy_seal($plaintext, $public_key);

// Elsewhere: 
$secret_key = file_get_contents('/path/to/secretkey.pem');
$visible = easy_unseal($store_me, $secret_key);

演示:https ://3v4l.org/BNavp

于 2015-10-07T06:35:19.420 回答
0

实际上,我也在一个类似的项目中,我正在尝试在 MySQL 服务器中构建一个安全数据库,该数据库对于运行所有有效的 SQL 查询也很有用。还在进行中,困难太多;我接受。

但是,对于您的问题,您似乎只需要加密和解密这些值。并且您不想将密钥也存储在数据库中。对我来说,有两种方式出现在我的脑海中:

  1. 第一种方法是,您决定一个固定的密钥来加密和解密这些值,并将其用于存储在数据库中的每个数据。
    但是,我猜这不切实际,因为这种方法的安全性很弱,而且人们可以通过暴力方法识别您的密钥。

  2. 第二种方式是,您在注册时为每个不同的用户生成一个随机密钥。而不同用户的数据只有拥有解密密钥的用户才能查看,这里只有用户拥有。然后在此之后应用第一种方法。即,您决定将用于加密不同用户的这些密钥的密钥。然后将此加密密钥存储在数据库中的单独表中。这样,下次用户尝试访问他/她的数据时,他输入的密钥(可能是他的密码)将使用您确定的静态密钥进行加密,如果在您的数据库表中找到此加密密钥,您将获取该用户的数据,用他/她的密钥解密并显示给他/她。
    您所需要的只是一个,
    (i) 可供选择的编程平台,JAVA 是最好的。
    (ii) 学习如何使用这种编程语言使用数据库,MySQL Server 是一个不错的选择。(iii) 以及一个很好的加密算法来实现。

希望,我没有让你对这个答案生气 :) 干杯。

于 2016-06-08T12:37:27.493 回答