Расшифровка с openssl_private_decrypt не будет работать, потому что текст хранит апострофы - PullRequest
1 голос
/ 10 ноября 2010

Я храню конфиденциальную информацию в базе данных mysql в формате текстового поля, которое шифруется с использованием openssl_public шифрования и расшифровывается с использованием openssl_private_decrypt.

Однако проблема, с которой я сталкиваюсь, заключается в том, что при попытке использовать мой php-скрипт для «декодирования» текста возвращаемое значение содержит несколько апострофов и цитат, поэтому дешифрование невозможно. Есть идеи как это исправить?

Примечание. Сначала я пытался сохранить информацию в поле типа «varbinary», но расшифровка каждый раз приводила к отказу.

Просмотрев еще несколько, я думаю, что php и mysql трудно обрабатывать всю информацию (~ 800 записей), потому что иногда поля остаются пустыми, а иногда нет. Если я сохраняю одну за другой, это работает с нулевыми проблемами, но при попытке выполнить цикл foreach почти всегда вызывает ошибки. Есть идеи? Скрипт для кодирования ниже:

<?php

$publickey = file_get_contents("certificate.pem");

function encrypt($text) 
    { 
        return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SALT, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)))); 
    } 


    try {
        $db = new PDO('mysql:host=localhost;dbname=DBNAME', 'USER', 'PW');
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $db->beginTransaction();

        $start = microtime(true);

        $stmt = $db->prepare("SELECT ID, ITEM1_old, ITEM2_old  FROM tablename");

        $stmt->execute();

        $rows = $stmt->fetchAll();

        foreach($rows as $row) {

            $id = $row['0'];
            $item1 = $row['1'];
            $item2 = $row['2'];

            define('SALT', $id);

            $item1_enc = encrypt($item1);
            $item2_enc = encrypt($item2);

            openssl_public_encrypt($item1_enc, $item1_ssl_enc, $publickey);
            openssl_public_encrypt($item2_enc, $item2_ssl_enc, $publickey);

            $stmt2 = $db->prepare("UPDATE tablename SET ITEM1_new=?, ITEM2_new=? WHERE ID=?");
            $stmt2->execute(array($item1_ssl_enc, $item2_ssl_enc, $id));

        }   

        $db->commit();
        $db->NULL;

        $elapsed = microtime(true) - $start;
        echo "Finished.<br />Elapsed time: ".$elapsed;
    }

    catch (PDOException $e)
    {
        $db->rollback();
        echo "There was a system error.".$e->getMessage();          
    }
?>

1 Ответ

1 голос
/ 01 марта 2011

Проблема в том, что шифры шифруются блоками, если ваш обычный текст не совпадает с размером блока шифра, он будет дополнен.Это нормально и правильно, вам нужно упаковать поле длины в данные до того, как вы его зашифруете следующим образом.

$plaintext  = 'text to encrypt';
$plaintext  = pack('V', strlen($plaintext)) . $plaintext;
$ciphertext = encrypt($plaintext);

Затем, чтобы получить обратно результат:

$plaintext = decrypt($ciphertext);
$header    = unpack('Vsize', $plaintext);
$plaintext = substr($plaintext, 4, $header['size'] + 4);

Кроме того, если ваша полезная нагрузка превышает сто байт или меньше, вы не должны использовать RSA для шифрования всей полезной нагрузки, вы должны сгенерировать случайный ключ, зашифровать полезную нагрузку с помощью ключа, а затем зашифровать ключ с помощью вашего открытого / частногоключ.RSA не предназначен для шифрования больших полезных нагрузок, он предназначен для совместного использования секрета для инициализации более быстрого симметричного шифра, такого как Blowfish.

Например.

/* Generate the random key */
$key = '';
for($i = 0; $i < 255; ++$i)
  $key .= chr(mt_rand(0, 255));
$key = sha1($key);

/* Pack & encrypt the payload with the key */
$plaintext  = pack('V', strlen($plaintext)) . $plaintext;
$ciphertext = encrypt($plaintext, $key);

/* Encrypt the key with the public key */
$key     = public_encrypt($key);
$payload = pack('V', strlen($key)) . $key . $ciphertext;

Для расшифровки

  1. распаковка длины ключа полезной нагрузки
  2. декодирование зашифрованного ключа с использованием открытого ключа
  3. декодирование зашифрованного текста с использованием расшифрованного ключа.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...