簡體   English   中英

從 MySQL 純數據庫值遷移到完全 AES 加密的值 (PHP APi)

[英]Migrating from MySQL plain database values to fully AES encrypted values (PHP APi)

短的:

由於 GDPR 法規,從純文本數據庫值遷移到完全/完全加密值的最佳方法是什么?

講解員:

我剛剛收到一個“提示”,由於 GDPR(歐盟通用數據保護條例)法律要求的新“設計隱私”概念,所有“敏感”信息都需要加密。 這包括姓名、地址、社交媒體資料、..

我們目前正在為 2000 多個用戶運行一個完整的生產數據庫,只能通過我們的 PHP REST API 訪問,該 API 用作所有 Web 和移動應用程序的入口點(尚無第三方開發人員)。 該數據庫包含當前以純文本形式存儲的電子郵件地址、地址、社交媒體句柄、名稱、IP 地址......(除了基於安全的敏感信息,如密碼、令牌......或用於身份驗證的任何其他值/鑒別)。

我不是這個(開發明智的)的忠實粉絲,因為它對性能、搜索算法、整個 PHP API 等的主要影響(感覺就像整個優化和“完美設置數據庫”的結束),但因為它是必需的因為它是額外的保護層,所以我全力以赴。

現在,我主要關心的是..一切都在積極運行,我們不能只是說“好吧,關閉服務器,加密一切,部署新的 API 版本並重新打開它。”。 此外,我認為這種遷移不能“一步一步”完成,所有事情都必須一次完成。 如果 API 未准備好處理所有查詢中的解密,則無法加密數據庫值,反之亦然,如果 API 期望對所有內容進行加密,則數據庫不能是純文本。

(我很高興我將整個 API 類型的交易作為數據庫的唯一入口/讀取點,沒有自定義腳本/連接,所以這是一種解脫)

我們正在運行一個功能強大的 VPS 服務器,因此由於冗余檢查和諸如此類的東西是一種選擇,因此會造成一些性能損失,而且我們也在運行暫存/開發環境,因此測試沒有問題。

例如,我會讓 MySQL 使用基於 ID(主鍵)和創建時間戳的組合的每個記錄的唯一鍵來處理 AES(這兩個值都不會改變)(這可能不是那么聰明)想法萬一“出於某種原因”這個值確實改變了,數據消失了..所以不確定),所以我的PHP應用程序在運行查詢時不需要以純文本形式傳達密鑰,但又一次, “創建用於解密的密鑰”仍將在查詢日志等中可見,因此“最安全”的方法是讓 PHP 應用程序加密和解密所有傳入/傳出數據,但這將導致無法例如,運行“搜索查詢”(除非我在這些特定查詢中發送密鑰......)。

我的問題:

怎么辦呢..? 我應該讓 PHP 處理加密/解密還是更可取的 MySQL? 當記錄被請求時,是否有一種可用的方法可以沿途遷移到加密值? ..?

我的想法是不接觸任何數據庫值(除了更新每個非整數列以處理當前指定的字符數量的 2-3 倍),這可以在不影響生產的情況下完成。 然后逐步更新所有 API 查詢,以檢查所選值是否已加密。 當一個部分運行正常時,更新該部分的表以加密所有值。 作為一個(簡單的)例子

MySQL方式; 每個 SELECT 查詢:

SELECT IF_AES_ENCRYPTED(first_name, AES_DECRYPT(first_name), first_name) AS first_name FROM contacts WHERE id = 1;

(或)PHP 方式:檢索數據:

while ($row = $result->fetch_assoc()) {
  $contact->setFirstName((IS_AES_ENCRYPTED($row['first_name']) ? AES_DECRYPT($row['first_name']) : $row['first_name']);
}

在部署結束時:

UPDATE contacts SET first_name = AES_ENCRYPT(first_name);

肯定有方法可以做到這一點,但由於我是此時唯一的開發人員,我只是不確定最實用/最有效的方法是什么,或者我是否過度或低估了這一點或不。 只是尋找其他已經執行過這樣的遷移/更新的開發人員。

謝謝,伯特。

我會通過添加一個新列first_name_enc來存儲字符串的加密版本來做到這一點。

然后,您可以在過渡到完全加密時臨時存儲加密和未加密的值。

ALTER TABLE contacts ADD COLUMN first_name_enc VARBINARY(...);

當您讀取值時,對其進行解密,但如果該值為 NULL,則它必須是尚未轉換的行,因此請回退到原始未加密列。

SELECT COALESCE(AES_DECRYPT(first_name_enc, <key-string>), first_name) ...

在整個應用程序中放置此代碼后,您就可以開始批量轉換行:

UPDATE contacts SET
  first_name_enc = AES_ENCRYPT(first_name, <key-string>), 
  first_name = NULL
WHERE id BETWEEN 1 AND 1000;

完成將所有內容轉換為加密后,您的應用程序不再插入未加密的列,然后您可以將條件查詢轉換為簡單地讀取加密列並解密它們。

SELECT AES_DECRYPT(first_name_enc, <key-string>) ...

然后最后刪除未加密的列,因為它們現在只包含 NULL 值。

ALTER TABLE contacts DROP COLUMN first_name;

我建議您在投入時間從事這項工作之前確認您真正需要做的有關加密的工作。 我讀過一些文章聲稱 GDPR 實際上並未強制要求加密。 https://www.i-scoop.eu/gdpr-encryption/

但對互聯網文章持保留態度。 咨詢合格的專家。 即使向專業專家支付咨詢費,也可能為您節省數萬美元的軟件開發成本!

暫無
暫無

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

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