Clob を暗号化する最良の方法は何ですか?
-
01-07-2019 - |
質問
Oracle 9 と JDBC を使用しており、DB に挿入されるときに Clob を暗号化したいと考えています。理想的には、プレーンテキストを挿入し、ストアド プロシージャで暗号化できるようにしたいと考えています。
String SQL = "INSERT INTO table (ID, VALUE) values (?, encrypt(?))";
PreparedStatement ps = connection.prepareStatement(SQL);
ps.setInt(id);
ps.setString(plaintext);
ps.executeUpdate();
平文は 4000 文字を超えることはないと予想されますが、暗号化するとテキストが長くなります。現在の暗号化アプローチでは dbms_obfuscation_toolkit.DESEncrypt() を使用しますが、処理するのは varchar のみです。以下は機能しますか?
FUNCTION encrypt(p_clob IN CLOB) RETURN CLOB
IS
encrypted_string CLOB;
v_string CLOB;
BEGIN
dbms_lob.createtemporary(encrypted_string, TRUE);
v_string := p_clob;
dbms_obfuscation_toolkit.DESEncrypt(
input_string => v_string,
key_string => key_string,
encrypted_string => encrypted_string );
RETURN UTL_RAW.CAST_TO_RAW(encrypted_string);
END;
一時的な Clob について混乱しています。閉める必要がありますか?それとも完全に道を外れたのでしょうか?
編集:難読化の目的は、データへの簡単なアクセスを防ぐことです。私のもう 1 つの目的は、既に varchar 列を難読化しているのと同じ方法で、clob を難読化することです。Oracle のサンプル コードは Clob を扱っていません。これが私の問題の原因です。varchar (2000 文字未満) の暗号化は簡単です。
解決
Oracle 9 を使用していることに注意してください。ただし、Oracle 10g 以降では、dbms_obfuscation_toolkit が廃止され、dbms_crypto が使用されるようになりました。
dbms_crypto CLOB サポートが含まれています。
DBMS_CRYPTO.ENCRYPT(
dst IN OUT NOCOPY BLOB,
src IN CLOB CHARACTER SET ANY_CS,
typ IN PLS_INTEGER,
key IN RAW,
iv IN RAW DEFAULT NULL);
DBMS_CRYPT.DECRYPT(
dst IN OUT NOCOPY CLOB CHARACTER SET ANY_CS,
src IN BLOB,
typ IN PLS_INTEGER,
key IN RAW,
iv IN RAW DEFAULT NULL);
他のヒント
Oracle のドキュメントに例があります。
http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96612/d_obtoo2.htm
閉じる必要はありません
DECLARE
input_string VARCHAR2(16) := 'tigertigertigert';
raw_input RAW(128) := UTL_RAW.CAST_TO_RAW(input_string);
key_string VARCHAR2(8) := 'scottsco';
raw_key RAW(128) := UTL_RAW.CAST_TO_RAW(key_string);
encrypted_raw RAW(2048);
encrypted_string VARCHAR2(2048);
decrypted_raw RAW(2048);
decrypted_string VARCHAR2(2048);
error_in_input_buffer_length EXCEPTION;
PRAGMA EXCEPTION_INIT(error_in_input_buffer_length, -28232);
INPUT_BUFFER_LENGTH_ERR_MSG VARCHAR2(100) :=
'*** DES INPUT BUFFER NOT A MULTIPLE OF 8 BYTES - IGNORING
EXCEPTION ***';
double_encrypt_not_permitted EXCEPTION;
PRAGMA EXCEPTION_INIT(double_encrypt_not_permitted, -28233);
DOUBLE_ENCRYPTION_ERR_MSG VARCHAR2(100) :=
'*** CANNOT DOUBLE ENCRYPT DATA - IGNORING EXCEPTION ***';
-- 1. Begin testing raw data encryption and decryption
BEGIN
dbms_output.put_line('> ========= BEGIN TEST RAW DATA =========');
dbms_output.put_line('> Raw input : ' ||
UTL_RAW.CAST_TO_VARCHAR2(raw_input));
BEGIN
dbms_obfuscation_toolkit.DESEncrypt(input => raw_input,
key => raw_key, encrypted_data => encrypted_raw );
dbms_output.put_line('> encrypted hex value : ' ||
rawtohex(encrypted_raw));
dbms_obfuscation_toolkit.DESDecrypt(input => encrypted_raw,
key => raw_key, decrypted_data => decrypted_raw);
dbms_output.put_line('> Decrypted raw output : ' ||
UTL_RAW.CAST_TO_VARCHAR2(decrypted_raw));
dbms_output.put_line('> ');
if UTL_RAW.CAST_TO_VARCHAR2(raw_input) =
UTL_RAW.CAST_TO_VARCHAR2(decrypted_raw) THEN
dbms_output.put_line('> Raw DES Encyption and Decryption successful');
END if;
EXCEPTION
WHEN error_in_input_buffer_length THEN
dbms_output.put_line('> ' || INPUT_BUFFER_LENGTH_ERR_MSG);
END;
dbms_output.put_line('> ');
少し話が逸れました:そもそも暗号化/難読化には何の意味があるのでしょうか?データベースにアクセスできる攻撃者は、平文を取得できます。上記のストアド プロシージャを見つけると、攻撃者は復号化を実行できるようになります。