2015-05-22 88 views
1

我有以下代碼...PHP中的AES-256和安全存儲密鑰?

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
    $iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM); 
    $key = pack("H*", "Insert64CharacterStringHere"); 

    $value = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $value, MCRYPT_MODE_CBC, $iv); 

    $value = $iv . ":" . $value; 

我使用這個在我的網站在AES-256加密數據。我將初始化向量與正在加密的數據一起存儲,並且數據和初始化向量之間是一個冒號,以便稍後可以將字符串分解爲初始化向量和數據,然後解密。

我想知道的是存儲密鑰的地方。如果我將它存儲在同一個數據庫中,它幾乎與不加密一樣不安全。我有一種感覺,把我的PHP代碼放在某處的鑰匙同樣不安全。

密鑰存儲在哪裏?這是存儲初始化向量的適當方法嗎?我是否安全地使用冒號作爲分隔符? I.E.初始化向量或數據是否會包含冒號?

+1

除非你想讓某人身臨其境地在每次解密發生時輸入密碼,否則你將不得不以純文本的形式將密鑰*存儲在服務器上。您可以在應用程序和密鑰之間放置多層混淆,但事實是解密在某個時刻需要明文密鑰。他們的休息。 – Sammitch

回答

4

部分答案...

這是一種適當的方式來存儲初始化向量?我是否安全地使用冒號作爲分隔符? I.E.初始化向量或數據是否會包含冒號?

對於AES(在CBC模式下),IV總是16個字節。沒有必要有分隔符。您可以放心地使用substr()功能解密之前分裂IV和密文:

$iv = substr($encrypted, 0, 16); 
$ct = substr($encrypted, 16); 

如果你在一個多字節字符串的環境的時候,你應該使用mb_substr() like this

$iv = mb_substr($encrypted, 0, 16, '8bit'); 
$ct = mb_substr($encrypted, 16, mb_strlen($encrypted, '8bit'), '8bit'); 

事實上,自IV是隨機產生的,它可能在某個時間點包含結腸。每16次加密的預期值爲1。數據是否包含冒號並不重要,因爲您可能從頭開始搜索。

+0

不用於爆炸,如果我沒有記錯,那麼字符串會在每個冒號周圍分裂。 –

+0

@MaartenBodewes這種情況並非如此,但如果存在多個冒號,並且將其他冒號內爆,您仍然需要推斷哪個冒號是正確的。這是不值得的。 –

+1

我當然不贊成使用冒號Artjom。我只是提出一個小問題,「因爲你可能從一開始就在尋找」,但[默認情況下] [(爆炸)](http://php.net/explode)會在每個分隔符周圍進行拆分。因此,如果不設置「限制」,您也可能會在數據中分散冒號。 –