簡體   English   中英

用openssl_private_decrypt解密將不起作用,因為文本存儲了撇號

[英]Decrypting with openssl_private_decrypt wont work because text is storing apostrophes

我將敏感信息以“文本”字段格式存儲在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();          
    }
?>

問題是密碼以塊為單位進行加密,如果您的純文本不符合密碼的塊大小,它將被填充。 這是正常且正確的,您需要像這樣對數據進行加密之前將一個length字段打包到數據中。

$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. 使用解密后的密鑰對密文進行解碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM