diff --git a/README.md b/README.md index 877f984..9317004 100644 --- a/README.md +++ b/README.md @@ -56,8 +56,8 @@ This command DOES CHANGE the database!!! Be careful!! Only run it when old enc ``` update-encryption.php update-table --table=core_config_data\ - --id-field=config_id --field=value --key=NEW_KEY --key-index=1\ - --old-key-index=[0/1] + --id-field=config_id --field=value --key=NEW_KEY --key-number=1\ + --old-key-number=[0/1] --dump=rotation.sql --dry-run ``` diff --git a/update-encryption.php b/update-encryption.php index 324c655..fdcdeb8 100644 --- a/update-encryption.php +++ b/update-encryption.php @@ -38,6 +38,7 @@ 'dry-run' => false, 'key-number' => 1, 'old-key-number' => 0, + 'dump' => false, 'output' => 'encrypted-values.csv' ]; @@ -88,7 +89,7 @@ $key = $keyLines[$params['old-key-number']]; else exit("OLD KEY NUMBER IS WRONG, NO KEY WITH NUMBER " . $params['old-key-number'] . " FOUND IN app/etc/env.php\n"); - + } $crypt = new \Magento\Framework\Encryption\Adapter\SodiumChachaIetf($key); @@ -112,51 +113,65 @@ } if ($skipTable) continue; - - $data = $db->query("SELECT * FROM $table")->fetchAll(PDO::FETCH_ASSOC); - if (!$data) - continue; - foreach ($data as $row) { - $idField = ''; - $idValue = ''; - $isCoreConfigData = false; - if (preg_match("%core_config_data%", $table)) { - $idField = 'config_id'; - $idValue = $row['config_id']; - $isCoreConfigData = true; + + $offset = 0; + $limit = 1000; // Adjust the chunk size as needed + $moreRowsAvailable = true; + + while ($moreRowsAvailable) { + $query = $db->prepare("SELECT * FROM $table LIMIT :offset, :limit"); + $query->bindParam(':offset', $offset, PDO::PARAM_INT); + $query->bindParam(':limit', $limit, PDO::PARAM_INT); + $query->execute(); + $data = $query->fetchAll(PDO::FETCH_ASSOC); + + if (!$data) { + $moreRowsAvailable = false; } else { - foreach ($row as $fieldName => $value) { - if (preg_match('%_id$%', $fieldName)) { - $idField = $fieldName; - $idValue = $value; + foreach ($data as $row) { + $idField = ''; + $idValue = ''; + $isCoreConfigData = false; + if (preg_match("%core_config_data%", $table)) { + $idField = 'config_id'; + $idValue = $row['config_id']; + $isCoreConfigData = true; + } else { + foreach ($row as $fieldName => $value) { + if (preg_match('%_id$%', $fieldName)) { + $idField = $fieldName; + $idValue = $value; + } + } } - } - } - foreach ($row as $fieldName => $value) { - if (($value !== null) && preg_match("%^\d\:\d\:%", $value)) { - $chunks = explode(':', $value); - $decrypted = 'N/A'; - $reEncrypted = 'N/A'; - $path = $isCoreConfigData ? $row['path'] : 'N/A'; - if ($params['decrypt'] && isset($params['key'])) { - $decrypted = $crypt->decrypt(base64_decode($chunks[2])); - } - if ($params['re-encrypt'] && isset($params['key'])) { - $reEncrypted = sprintf("%d:3:%s", $params['key-number'], base64_encode($cryptNew->encrypt($decrypted))); - } - $update = [ - $table, $idField, $idValue, $path, $fieldName, $value, $decrypted, $reEncrypted - ]; - fputcsv($f, $update); - $encryptedField = sprintf("$table::$fieldName"); - if (!in_array($encryptedField, $encryptedFields)) { - $encryptedFields[] = $encryptedField; + foreach ($row as $fieldName => $value) { + if (($value !== null) && preg_match("%^\d\:\d\:%", $value)) { + $chunks = explode(':', $value); + $decrypted = 'N/A'; + $reEncrypted = 'N/A'; + $path = $isCoreConfigData ? $row['path'] : 'N/A'; + if ($params['decrypt'] && isset($params['key'])) { + $decrypted = $crypt->decrypt(base64_decode($chunks[2])); + } + if ($params['re-encrypt'] && isset($params['key'])) { + $reEncrypted = sprintf("%d:3:%s", $params['key-number'], base64_encode($cryptNew->encrypt($decrypted))); + } + $update = [$table, $idField, $idValue, $path, $fieldName, $value, $decrypted, $reEncrypted]; + fputcsv($f, $update); + $encryptedField = sprintf("$table::$fieldName"); + if (!in_array($encryptedField, $encryptedFields)) { + $encryptedFields[] = $encryptedField; + } + } } + $offset += $limit; + } } + } - } + fclose($f); print_r($encryptedFields); } else if ($command == 'update-table' || $command == 'update-record') { if (!isset($params['table'])) @@ -180,7 +195,10 @@ $recordFilter = sprintf(" AND `%s`='%d'", $idField, $id); $query = sprintf("SELECT * FROM `%s` WHERE `%s` LIKE '%d:3%%' %s", $table, $field, $keyNumber, $recordFilter); echo $query . "\n"; - $data = $db->query($query)->fetchAll(PDO::FETCH_ASSOC); + + $offset = 0; + $limit = 1000; // Adjust the chunk size as needed + $moreRowsAvailable = true; $fileHandler = null; $backupHandler = null; @@ -188,25 +206,42 @@ $fileHandler = fopen($params['dump'], 'a'); $backupHandler = fopen('backup-' . $params['dump'], 'a'); } - foreach ($data as $row) { - $value = $row[$field]; - $chunks = explode(':', $value); - $decrypted = $crypt->decrypt(base64_decode($chunks[2])); - $reEncrypted = sprintf("%d:3:%s", $params['key-number'], base64_encode($cryptNew->encrypt($decrypted))); - - echo "UPDATING row $idField=" . $idField . ", $field=" . $row[$field] . "; New value = " . $reEncrypted . "\n"; - $updateQuery = sprintf("UPDATE `%s` SET `%s`='%s' WHERE `%s`='%d' LIMIT 1;", $table, $field, $reEncrypted, $idField, $row[$idField]); - $backupQuery = sprintf("UPDATE `%s` SET `%s`='%s' WHERE `%s`='%d' LIMIT 1;", $table, $field, $value, $idField, $row[$idField]); - - if ($params['dump']) { - fwrite($fileHandler, $updateQuery . "\n"); - fwrite($backupHandler, $backupQuery . "\n"); - } - echo " " . $updateQuery . "\n"; - if (!isset($params['dry-run']) || !$params['dry-run']) { - echo "UPDATING !\n"; - $db->query($updateQuery); + while ($moreRowsAvailable) { + $query = sprintf("SELECT * FROM `%s` WHERE `%s` LIKE '%d:3%%' %s LIMIT :offset, :limit", $table, $field, $keyNumber, $recordFilter); + $stmt = $db->prepare($query); + $stmt->bindParam(':offset', $offset, PDO::PARAM_INT); + $stmt->bindParam(':limit', $limit, PDO::PARAM_INT); + $stmt->execute(); + $data = $stmt->fetchAll(PDO::FETCH_ASSOC); + + if (!$data) { + $moreRowsAvailable = false; + } else { + foreach ($data as $row) { + $value = $row[$field]; + $chunks = explode(':', $value); + $decrypted = $crypt->decrypt(base64_decode($chunks[2])); + $reEncrypted = sprintf("%d:3:%s", $params['key-number'], base64_encode($cryptNew->encrypt($decrypted))); + + echo "UPDATING row $idField=" . $idField . ", $field=" . $row[$field] . "; New value = " . $reEncrypted . "\n"; + $updateQuery = sprintf("UPDATE `%s` SET `%s`='%s' WHERE `%s`='%d' LIMIT 1;", $table, $field, $reEncrypted, $idField, $row[$idField]); + $backupQuery = sprintf("UPDATE `%s` SET `%s`='%s' WHERE `%s`='%d' LIMIT 1;", $table, $field, $value, $idField, $row[$idField]); + + if ($params['dump']) { + fwrite($fileHandler, $updateQuery . "\n"); + fwrite($backupHandler, $backupQuery . "\n"); + } + echo " " . $updateQuery . "\n"; + if (!isset($params['dry-run']) || !$params['dry-run']) { + echo "UPDATING !\n"; + $db->query($updateQuery); + } + } } + $offset += $limit; + } + if ($params['dump']) { + fclose($fileHandler); + fclose($backupHandler); } } -