2013-10-09 51 views
0

php mcrypt_decrypt不考慮null輸入(密碼)數據中的字符。 (顯然它在空字符的第一次同意時結束)。如何使用空字符解密數據?我不想使用base64 encoding,因爲加密將輸出空字符,所以它不會起作用。php mcrypt_decrypt不考慮數據中的空字符

[編輯] 返回類型也是字符串,所以用空字符輸出被截斷。這是什麼方式?還是有任何其他的加密庫,我應該使用緩衝區而不是字符串?

+0

其實我沒有這個問題,只有尾隨\ 0字符是一個問題,因爲塊密碼將填充\ 0字符的原始輸入塊大小。是否有可能在別處丟失了部分字符串,例如當存儲在數據庫或字符串函數? – martinstoeckli

+0

不是拖尾(填充)的空值。我已經加密了這樣的數據:「abcd \ 0efgh」,它將被解密。請參閱位置5處的空值。 – user1288043

+0

您使用的算法是什麼?你能提供你的部分代碼嗎?我只是加倍檢查並嘗試用[示例](http://www.martinstoeckli.ch/php/php.html#bcrypt)中的代碼加密「abcd \ 0efgh」,向下滾動以查找函數'encryptTwofish()'和'decryptTwofish()'。 – martinstoeckli

回答

0

mcrypt庫適用於包含\ 0字符的數據。也許你在別處丟失了一部分字符串,可能在打印結果之前使用字符串函數。

我剛剛檢查了這個例子,它解密後返回了\ 0個字符。如果您需要AES加密,則可以使用MCRYPT_RIJNDAEL_256替換MCRYPT_TWOFISH。

/** 
* Encrypts data with the TWOFISH algorithm. The IV vector will be 
* included in the resulting binary string. 
* @param string $data Data to encrypt. Trailing \0 characters will get lost. 
* @param string $key This key will be used to encrypt the data. The key 
* will be hashed to a binary representation before it is used. 
* @return string Returns the encrypted data in form of a binary string. 
*/ 
public static function encryptTwofish($data, $key) 
{ 
    if (!defined('MCRYPT_DEV_URANDOM')) throw new Exception('The MCRYPT_DEV_URANDOM source is required (PHP 5.3).'); 
    if (!defined('MCRYPT_TWOFISH')) throw new Exception('The MCRYPT_TWOFISH algorithm is required (PHP 5.3).'); 

    // The cbc mode is preferable over the ecb mode 
    $td = mcrypt_module_open(MCRYPT_TWOFISH, '', MCRYPT_MODE_CBC, ''); 

    // Twofish accepts a key of 32 bytes. Because usually longer strings 
    // with only readable characters are passed, we build a binary string. 
    $binaryKey = hash('sha256', $key, true); 

    // Create initialization vector of 16 bytes 
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_DEV_URANDOM); 

    mcrypt_generic_init($td, $binaryKey, $iv); 
    $encryptedData = mcrypt_generic($td, $data); 
    mcrypt_generic_deinit($td); 
    mcrypt_module_close($td); 

    // Combine iv and encrypted text 
    return $iv . $encryptedData; 
} 

/** 
* Decrypts data, formerly encrypted with @see encryptTwofish. 
* @param string $encryptedData Binary string with encrypted data. 
* @param string $key This key will be used to decrypt the data. 
* @return string Returns the original decrypted data. 
*/ 
public static function decryptTwofish($encryptedData, $key) 
{ 
    if (!defined('MCRYPT_TWOFISH')) throw new Exception('The MCRYPT_TWOFISH algorithm is required (PHP 5.3).'); 

    $td = mcrypt_module_open(MCRYPT_TWOFISH, '', MCRYPT_MODE_CBC, ''); 

    // Extract initialization vector from encrypted data 
    $ivSize = mcrypt_enc_get_iv_size($td); 
    $iv = substr($encryptedData, 0, $ivSize); 
    $encryptedData = substr($encryptedData, $ivSize); 

    $binaryKey = hash('sha256', $key, true); 

    mcrypt_generic_init($td, $binaryKey, $iv); 
    $decryptedData = mdecrypt_generic($td, $encryptedData); 
    mcrypt_generic_deinit($td); 
    mcrypt_module_close($td); 

    // Original data was padded with 0-characters to block-size 
    return rtrim($decryptedData, "\0"); 
} 
+0

也許加密沒有問題。 filesize()給我stale文件大小,所以它從文件中讀取不正確的字節數。用clearstatcache()固化。文件大小緩存?大! – user1288043

+0

另外MCRYPT_RIJNDAEL_256使用與16字節不同的塊大小。這是libmcrypt中的一個[bug](https://bugs.php.net/bug.php?id=47125)。 – user1288043

+0

@ user1288043 - 很高興聽到您解決了您的問題。不同的塊大小在實踐中應該沒有問題,無論如何你都可以正確地加密和解密數據。文章只意味着它不符合規範,我不能判斷。 – martinstoeckli