2008-09-18 16 views
3

J'utilise Oracle 9 et JDBC et j'aimerais encyrter un objet clob lorsqu'il est inséré dans la base de données. Idéalement, je voudrais pouvoir vous suffit d'insérer le texte en clair et l'avoir crypté par une procédure stockée:Quelle est la meilleure façon de chiffrer un clob?

String SQL = "INSERT INTO table (ID, VALUE) values (?, encrypt(?))"; 
PreparedStatement ps = connection.prepareStatement(SQL); 
ps.setInt(id); 
ps.setString(plaintext); 
ps.executeUpdate(); 

Le texte brut ne devrait pas dépasser 4000 caractères, mais rend le texte plus encryptage. Notre approche actuelle du cryptage utilise dbms_obfuscation_toolkit.DESEncrypt() mais nous ne traitons que les varchars. Est-ce que ce qui suit fonctionnera?

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; 

Je suis confus au sujet de la clob temporaire; Ai-je besoin de le fermer? Ou suis-je totalement hors piste?

Éditer: Le but de l'obfuscation est d'empêcher un accès trivial aux données. Mon autre but est d'obscurcir les clobs de la même manière que nous obscurcissons déjà les colonnes varchar. L'exemple de code oracle ne traite pas des clobs qui sont où mon problème spécifique se trouve; le cryptage de varchars (plus petit que 2000 caractères) est simple.

Répondre

0

Je remarque que vous êtes sur Oracle 9, mais juste pour l'enregistrement dans Oracle 10g + le dbms_obfuscation_toolkit a été déprécié en faveur de dbms_crypto.

dbms_crypto ne comprend 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); 
2

Il est un exemple dans la documentation Oracle:

http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96612/d_obtoo2.htm

Vous n'êtes pas obligé de le fermer

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('> '); 
+0

Cela ne répond pas vraiment à la question; pour un il n'utilise pas CLOBS et pour deux il n'a pas la même sémantique que la fonction d'origine: function encrypt (texte en clob) return clob - renvoie le texte chiffré –

1

légèrement hors-sujet: Quel est le point du chiffrement/obscurcissement dans la première place? Un attaquant ayant accès à votre base de données sera en mesure d'obtenir le texte en clair - trouver la procédure stockée ci-dessus permettra à l'attaquant d'effectuer le déchiffrement.

+0

La clé ne doit pas être stockée dans votre base de données, mais passé à partir de l'application. –

+0

Je suis d'accord avec le commentaire, mais le code d'origine ne transmet aucune clé à la fonction de cryptage. – Alexander

+0

Avoir une sauvegarde avec les données non encodées peut être un problème de sécurité. Quoi qu'il en soit, je suis d'accord que le document voyagera non codé sur le réseau, mais à cette fin, il est préférable de chiffrer toute la connexion avec https. – borjab