【问题标题】:Encrypting / Decrypting Lists of data efficiently有效地加密/解密数据列表
【发布时间】:2014-10-31 01:17:28
【问题描述】:

我有一个加密的 JSON 对象,其中包含使用 AES 和 RSA 加密的数据列表。

<?php

    function decrypt_data($encrypted_data, $session_key)
    {
        $decrypt = explode('|', $encrypted_data);
        $decoded = base64_decode($decrypt[0]);
        $iv = base64_decode($decrypt[1]);
        $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $session_key, $decoded, MCRYPT_MODE_CBC, $iv);
        $decrypted = unserialize($decrypted);

        return $decrypted;
    }

    function encrypt_session_key($session_key)
    {
        $sealed ="";
        $ekeys="";
        $pubKey[] = openssl_pkey_get_public("file:///public.pem");
        $result = openssl_seal($session_key, $sealed, $ekeys, $pubKey);
        $encrypted_session_key = array( 'encdata' => base64_encode($sealed), 'enckey' => base64_encode(serialize($ekeys)) );
        return $encrypted_session_key;
    }

    $data = '{"index":{"12345":{"title":"title 1","date_modified":1029232323},"23456":{"title":"title 2","date_modified":1029232323}},"archived":{}}';
    $session_key = openssl_random_pseudo_bytes(32);
    $encrypted_data = encrypt_data($session_key, $data);
    $encrypted_session_key = encrypt_session_key($session_key);
    $session_key = null;
    $encrypted_session_key_data = $encrypted_session_key['encdata'];
    $encrypted_session_key_keys = $encrypted_session_key['enckey'];

    // the encrypted data
    $the_encrypted_data = array("data_key" => $encrypted_session_key_data, "encryption_data_key" => $encrypted_session_key_keys, "data" => $encrypted_data);
?>

每次用户加载他们的仪表板时,我都会解密数据并使用 dataTables 将其列在表格中。

<?php

    function decrypt_session_key($encrypted_session, $env_key)
    {
        $private_key = openssl_get_privatekey("file:///private.pem", "password");
        openssl_open(base64_decode($encrypted_session), $open, unserialize(base64_decode($env_key))[0], $private_key);

        return $open;
    }

    function decrypt_data($encrypted_data, $session_key)
    {
        $decrypt = explode('|', $encrypted_data);
        $decoded = base64_decode($decrypt[0]);
        $iv = base64_decode($decrypt[1]);
        $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $session_key, $decoded, MCRYPT_MODE_CBC, $iv);
        $decrypted = unserialize($decrypted);
        return $decrypted;
    }

    $decrypted_key = decrypt_session_key($data_key, $encryption_data_key);
    $the_decrypted_data = json_decode(decrypt_data($data, $decrypted_key), true);

?>

当列表中有大约 10-100 多个项目时,加载列表需要 8-10 秒,我假设是因为解密数据需要一些时间。

随着我的表格加起来,有没有人对如何使整个过程更快一点有任何建议?一旦我在这个列表中有 1000 甚至 10,000 条数据,我不希望它花费很长时间。

唯一的规定是,数据必须加密。

【问题讨论】:

    标签: php encryption cryptography aes rsa


    【解决方案1】:

    大部分时间可能都花在了会话密钥的 RSA 解密上。 RSA 比 AES 慢得多。最好的办法可能是为多个字段创建一个会话单个密钥并解密一次。目前它们无论如何都依赖于相同的私钥,因此在密钥管理方面并不重要。您已经为每个字段提供了一个随机 IV,因此加密本身应该是安全的。

    您可以进行的另一个小改动是实际使用 AES。 MCRYPT_RIJNDAEL_256 是 Rijndael,块大小为 256 位而不是 128 位。块大小为 128 位 (MCRYPT_RIJNDAEL_1282) 的 Rijndael 等于 AES - 目前您无法使用仅 AES 的库进行解密。密钥大小取决于会话密钥的大小。

    另一个解决方法是切换到椭圆曲线 EC 密钥对并使用 ECIES。这对于解密来说要快得多(对于加密来说只是稍微慢一点)。如果您还不了解椭圆曲线密码学,这将需要一个陡峭的学习曲线。

    最后,与不支持 AES-NI 指令集的 mcrypt 相比,OpenSSL 在 Intel 平台上会更快(目前据我所知 - C-lib 已经连续多年没有更新)。但是,PHP OpenSSL API 非常有限,目前我无法在这里提供帮助。

    【讨论】:

    • 注意:我还没有对代码进行完整的代码审查。
    【解决方案2】:

    也许你可以使用多个ajax请求来模拟多线程解密。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-30
      • 1970-01-01
      • 1970-01-01
      • 2013-09-18
      • 2021-03-16
      • 1970-01-01
      • 1970-01-01
      • 2011-03-12
      相关资源
      最近更新 更多