加密mysql数据库

时间:2015-10-07 00:13:22

标签: php mysql encryption anonymize

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

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

我的哲学可能是错的,就是通过这样做来学习。希望你们对我的方法感到满意。

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

提前致谢:)!

PS:我实际上会遇到与文件相同的问题(jpg,word,pdf,xls ......应该足够用户)。但这是另一个故事。

3 个答案:

答案 0 :(得分:6)

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

但是,我相信您错过了一个重要的观点:如果您无法访问某些数据,那么该数据绝不能以普通格式到达您的组织。期。如果是,那么您已经可以访问它。因此,php(或任何类型的基于服务器的加密)或基于mysql的加密解决方案都无法实现。

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

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

  1. 由于PKI提供商必须是独立的第三方,因此它们不是他们所处理的单一提供商。您不得管理证书。
  2. 如果存储的数据损坏,加密的数据将丢失。因此,您必须实施一些疯狂的备份和恢复解决方案。

答案 1 :(得分:2)

所以假设问题如下:

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

实际上有一个工具:它被称为sealing 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

答案 2 :(得分:0)

实际上,我也在类似的项目中,我试图在MySQL Server中构建一个安全数据库,这对于运行所有有效的SQL查询也很有用。它仍在进步中,存在太多困难;我接受。

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

  1. 第一种方法是,您决定使用固定密钥来加密和解密值,并将其用于存储在数据库中的每个数据。
    但是,我认为这不实用,因为这种方法的安全性变弱了,一个人可以用蛮力方法识别你的密钥。

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

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