基本的に「ユーザー」と「データ」の2つの列で構成される「タブ」テーブルがあります。「ユーザー」はアプリケーション レベルのユーザー ID を指し、「データ」はユーザーが保存する機密情報を指します。
CREATE TABLE IF NOT EXISTS tab(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
user VARCHAR(255),
data BLOB
);
「データ」列の各ブロブを、それぞれのユーザーの個別のキーで暗号化する必要があります。このキーは、ユーザーのパスワードから計算され、ユーザーがログインしている間に一時テーブルに保存されます。暗号化と復号化を実行するには、定義しました2 つのストアド プロシージャ「encData」と「decData」。
ただし、落とし穴があります。暗号化スキームは、データベース上で実行されているすべてのアプリケーションに対して完全に透過的でなければなりません。テーブルと列の名前は変更しないでください。つまり、'tab.data' の SELECT ステートメントは暗黙的に 'decData' を呼び出す必要がありますが、INSERT と UPDATE は暗黙的に 'encData' を呼び出す必要があります。
私の現在の回避策は、次の 2 つの手順で構成されています。
- 'tab' の名前を 'tab_encrypted' に変更し、'tab' という名前のビューを作成します。これにより、列 'data' のすべての SELECT ステートメントが復号化されます。
ALTER TABLE tab RENAME TO tab_encrypted; CREATE OR REPLACE VIEW tab AS SELECT id, user, decData(data) AS data FROM tab_encrypted;
- 列「データ」での挿入または更新を暗号化するトリガーを作成します。
CREATE TRIGGER encOnInsert BEFORE INSERT ON tab_encrypted FOR EACH ROW SET NEW.data = encData(NEW.data); CREATE TRIGGER encOnUpdate BEFORE UPDATE ON tab_encrypted FOR EACH ROW SET NEW.data = encData(NEW.data);
残念ながら、ビュー 'tab' は派生列のため挿入も更新もできず、代わりに 'tab_encrypted' で挿入と更新を実行する必要があります。より良い回避策または代替アプローチを知っている人はいますか?
助けてくれてどうもありがとう、
1月