2010-09-15 82 views
1

我正在尋找一種將數據加密到MySQL數據庫的方法,並在出口時將其解密。此外,我希望能夠對這些字段執行正常的SQL查詢,例如搜索和比較,這使我無法使用純PHP解決方案。MySQL的AES_DECRYPT問題

這導致我使用AES_ENCRYPT()和AES_DECRYPT(),它可以使用MCRYPT在PHP中複製。

我很難與AES_DECRYPT並嘗試所有建議,我可以通過在線搜索找到。

這裏是我的表:

CREATE TABLE IF NOT EXISTS `test_table` (
    `id` int(6) NOT NULL, 
    `secure_info` text NOT NULL, 
    `encrypted_blob` blob NOT NULL, 
    `encrypted` text NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

我執行這些查詢:

INSERT INTO test_table (id, secure_info) VALUES (1,'Testing'); 
UPDATE test_table SET encrypted = AES_ENCRYPT(secure_info,'key') WHERE id=1 LIMIT 1; 
UPDATE test_table SET encrypted_blob = AES_ENCRYPT(secure_info,'key') WHERE id=1 LIMIT 1; 

SELECT *, AES_DECRYPT(encrypted,'key') as decrypted, AES_DECRYPT(encrypted_blob,'key') as decrypted_blob FROM test_table WHERE id=1; 

我無法得到原始值。 'decrypted'返回NULL,'decrypted_blob'返回54657374696e67

任何想法,或者更好的解決方案?

+0

所有加密是通過定義可逆的。您使用密碼混淆了消息摘要功能。翻譯md5()不加密其散列函數。 – rook 2010-09-16 01:51:42

+0

如果你只是想存儲加密值,你應該用PHP加密它們並將它們寫成斑點。這樣,密鑰永遠不會離開PHP,因此數據庫對攻擊者無用。你似乎在做的是在數據庫中進行加密和解密,這提供了更少的保護。畢竟,您現在必須通過每條查詢在電線上發送(純文本!)鍵。最後,Rook有一點,因爲如果你存儲密碼而不是加密,你應該使用摘要。 – 2010-09-18 02:09:26

回答

4

斑點解密工作得很好, 「54657374696e67」 是 「測試」,只有十六進制編碼。你可能用一個將blob顯示爲十六進制的工具來執行此操作。文本解密不起作用(也不應該)。

+0

謝謝 - 這是我遇到的最大麻煩。我的數據庫也設置在UNHEX()的出路上 - 當我選擇時,我會得到原始文本! – Travis 2010-09-17 22:22:07

+1

好的。你甚至沒有看到十六進制碼。所有你看到的是金髮,黑髮,紅髮,測試... – webbiedave 2010-09-20 15:03:52

0

AES_ENCRYPT返回一個二進制字符串,所以不要使用文本列類型。

提示:在1啓動主鍵編號,而不是0

提示2:儘量不要命名MySQL的關鍵字後,您的領域。這可能會導致混淆,通常需要使用反引號進行轉義(text是個例外)。

http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html

+0

不是AES_ENCRYPT只是返回值?我有兩個字段,'加密'和'encrypted_blob'進行測試,因爲我知道需要一個二進制字段。我已經用你的提示更新了我的代碼,結果也是一樣。非常有趣的提示;我一定會進一步研究它們。謝謝! – Travis 2010-09-15 19:00:27

+0

'AES_ENCRYPT'返回二進制數,因此不要將結果存儲在文本列中。你的第一個'UPDATE'將它存儲在一個文本列中。這可能導致加密/解密錯誤。 – webbiedave 2010-09-15 20:45:34

+0

謝謝 - 我的文字欄的目標是看看發生了什麼。我現在明白,二進制列是必要的,而文本列完全沒用。 – Travis 2010-09-17 22:19:51

2

MySQL中的TEXT字段受制於字符集轉換。如果您使用iso-8859連接並且表格存儲在CP1252中,那麼MySQL會自動轉換兩個字符集之間的文本。這會破壞加密的數據,因爲原始8859數據的一些字節將被轉換爲1252的等值,這些等值具有不同的值。

另一方面,BLOB字段是逐字傳遞的,沒有轉換,所以沒有錯誤解密。

+0

謝謝 - 這是非常有益的! – Travis 2010-09-17 22:24:11

0

如果您使用AES_ENCRYPT加密字符串,則AES_DECRYPT不會返回字符串,而是返回System.Byte的數組。我使用下面的代碼將其還原爲一個字符串:

  Dim back As System.Byte() 
      back = DirectCast(reader(x), System.Byte()) 
      Dim s As String = "" 
      For Each b As Byte In back 
       s &= Chr(b) 
      Next 
0

同意@ user187291

我有同樣的問題,並發現了我的phpmyadmin檢查選項

顯示二進制內容HEX

當我運行在MySQL命令行相同的查詢它顯示我正確的結果