У меня есть зашифрованный объект 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 фрагментов данных в этом списке.
Единственное условие, данные должен быть зашифрованным.
Большую часть времени, вероятно, займет расшифровка RSA сессионных ключей. RSA намного медленнее, чем AES. Вероятно, лучше всего создать единый ключ сеанса для нескольких полей и расшифровать его один раз. В настоящее время они все равно зависят от одного и того же закрытого ключа, так что это не имеет большого значения для управления ключами. Вы уже предоставляете случайный IV для каждого поля, поэтому само шифрование должно быть безопасным.
Еще одно небольшое изменение, которое вы можете сделать, — это использовать AES. MCRYPT_RIJNDAEL_256
Rijndael с размером блока 256 бит вместо 128 бит. Рейндаэль с размером блока 128 бит (MCRYPT_RIJNDAEL_1282
) равен AES — в настоящее время вы не сможете расшифровать только библиотеку AES. Размер ключа зависит от размера сеансового ключа.
Другим исправлением может быть переключение на пару ключей Elliptic Curve EC и использование ECIES. Это намного быстрее для расшифровки (и только немного медленнее для шифрования). Это потребует крутой кривой обучения, если вы еще не знаете криптографию Elliptic Curve.
Наконец, OpenSSL будет быстрее на платформах Intel по сравнению с mcrypt, который не поддерживает набор команд AES-NI (в настоящее время и, насколько мне известно, C-lib не обновлялась годами). Тем не менее, PHP OpenSSL API очень ограничен, и в настоящее время я не смог бы помочь здесь.
Может быть, вы можете использовать несколько запросов AJAX для имитации многопоточности дешифрования.