2014-10-31 75 views
1

我有一个加密的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条数据在这个列表中,我不希望它花费很长时间。

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

回答

0

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

1

大部分时间很可能会被会话密钥的RSA解密所采用。 RSA比AES慢得多。可能最好的做法是为多个字段创建一个会话单个密钥并解密一次。目前它们都依赖于相同的私钥,因此对于密钥管理来说无关紧要。您已经为每个字段提供了随机IV,因此加密本身应该是安全的。

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

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

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

+0

注意:我没有对代码执行完整的代码审查。 – 2014-10-31 11:42:05